#filter substitution package @ANDROID_PACKAGE_NAME@.tests; import @ANDROID_PACKAGE_NAME@.*; import android.view.ViewGroup; import android.view.View; import android.widget.ListView; import android.widget.TextView; import android.widget.ImageView; import android.text.TextUtils; import java.util.ArrayList; /** * Tests the Bookmarks Tab * - opening the bookmarks tab * - items look correct * - clicking on an item * - long tapping on an item * - editing the name, url and keyword of a bookmark from the context menu * - removing a bookmark */ public class testBookmarksTab extends BaseTest { private View mFirstChild; private ListView list; @Override protected int getTestType() { return TEST_MOCHITEST; } public void testBookmarksTab() { blockForGeckoReady(); String url = "http://www.example.com"; // add one page to desktop folders so that we can see them addOrUpdateBookmark("BOOKMARK_TITLE", url, false); testList(url); testContextMenu(url); } private void testList(String url) { View child; ListView list = getBookmarksList("about:firefox", 5); mAsserter.isnot(list, null, "checking that bookmarks list exists and has 5 children (defaults + a folder)"); int count = list.getAdapter().getCount(); for (int i = count - 1; i >= 0; i--) { child = list.getChildAt(i); compareRow(child, i == 0 ? 1 : 2, 1); } child = list.getChildAt(0); mAsserter.ok(child != null, "first list item can be retrieved", child != null ? child.toString() : "null!"); mSolo.clickOnView(child); waitForText("Bookmarks Toolbar"); count = list.getAdapter().getCount(); mAsserter.is(count, 4, "desktop folder has correct number of children"); for (int i = count - 1; i >= 0; i--) { child = list.getChildAt(i); compareRow(child, 1, i == 0 ? 0 : 1); } child = list.getChildAt(1); mAsserter.ok(child != null, "second list item can be retrieved", child != null ? child.toString() : "null!"); mSolo.clickOnView(child); waitForText("BOOKMARK_TITLE"); count = list.getAdapter().getCount(); mAsserter.is(count, 2, "toolbar folder has correct number of children"); for (int i = count - 1; i >= 0; i--) { child = list.getChildAt(i); compareRow(child, i == 0 ? 1:2, i == 0 ? 0:1); } // Test backing out of the folder using the back button mActions.sendSpecialKey(Actions.SpecialKey.BACK); mAsserter.ok(mSolo.waitForText("Bookmarks Toolbar"), "Back moved up one level", ""); mActions.sendSpecialKey(Actions.SpecialKey.BACK); mAsserter.ok(mSolo.waitForText("about:home"), "Back moved up one level", ""); mActions.sendSpecialKey(Actions.SpecialKey.BACK); } private void testContextMenu(String url) { list = getBookmarksList(url); // wait for the bookmarks list to be populated View child; mFirstChild = null; boolean success = waitForTest(new BooleanTest() { @Override public boolean test() { mFirstChild = list.getChildAt(1); if (mFirstChild == null) { return false; } if (mFirstChild instanceof android.view.ViewGroup) { ViewGroup group = (ViewGroup)mFirstChild; if (group.getChildCount() < 1) { return false; } for (int i = 0; i < group.getChildCount(); i++) { View grandChild = group.getChildAt(i); if (grandChild instanceof android.widget.TextView) { mAsserter.ok(true, "found TextView:", ((android.widget.TextView)grandChild).getText().toString()); } } } else { mAsserter.dumpLog("first child not a ViewGroup: "+mFirstChild); return false; } return true; } }, MAX_WAIT_MS); if (success == true && mFirstChild != null) { mAsserter.dumpLog("clickLongOnView: "+mFirstChild); // long tap on a bookmark should show a context menu with an edit option mSolo.clickLongOnView(mFirstChild); // TODO: Test clicking these does the right thing mAsserter.ok(mSolo.waitForText("Open in New Tab"), "Context menu has Open in New Tab option", "Open in New Tab"); mAsserter.ok(mSolo.waitForText("Share"), "Context menu has Share option", "Share"); mAsserter.ok(mSolo.searchText("Edit", true), "Context menu has Edit option", "Edit"); mAsserter.ok(mSolo.searchText("Remove", true), "Context menu has Remove option", "Remove"); mAsserter.ok(mSolo.searchText("Add to Home Screen", true), "Context menu has Add to Home Screen option", "Add to Home Screen"); // press back to exit the context menu mActions.sendSpecialKey(Actions.SpecialKey.BACK); // test long tap on a folder, this should fail but will still open the folder child = list.getChildAt(0); mAsserter.ok(child != null, "first list item can be retrieved", child != null ? child.toString() : "null!"); mSolo.clickLongOnView(child); mAsserter.is(mSolo.waitForText("Share"), false, "Folders have no context menu"); } else { mAsserter.ok(false, "waiting for bookmark item", "bookmark item available"); } list = getBookmarksList(url); // Test edit bookmark name editBookmark(1,0," Bookmark Name ",list); mAsserter.is(checkBookmarkEdit(1," Bookmark Name ",list), true, "Bookmark Name was changed"); // Test edit bookmark link editBookmark(1,1," Bookmark Link ",list); mAsserter.is(checkBookmarkEdit(1,"Bookmark Link",list), true, "Bookmark Link was changed"); // Test edit bookmark keyword editBookmark(1,2," BookmarkKeyword ",list); mAsserter.is(checkBookmarkEdit(1,"BookmarkKeyword",list), true, "Bookmark Keyword was changed"); // Remove Bookmark from Context Menu waitForText("Bookmarks"); child = list.getChildAt(1); mAsserter.ok(child != null, "second list item can be retrieved", child != null ? child.toString() : "null!"); mSolo.clickLongOnView(child); waitForText("Remove"); mSolo.clickOnText("Remove"); // Wait for the toaster notification waitForText("Bookmark removed"); // Verify Bookmark is removed child = list.getChildAt(1); mAsserter.ok(child != null, "second list item can be retrieved", child != null ? child.toString() : "null!"); mSolo.clickLongOnView(child); waitForText("Share"); mAsserter.is(mSolo.searchText("Bookmark Name"), false, "Removed bookmark has been deleted"); mActions.sendSpecialKey(Actions.SpecialKey.BACK); // Exit the Context Menu // back again to exit the awesomebar mActions.sendSpecialKey(Actions.SpecialKey.BACK); } private void compareRow(View child, int numTextViews, int numImageViews) { if (child == null) { // this list item may be obscured or offscreen mAsserter.dumpLog("ListView child not available for comparison - offscreen?"); return; } ArrayList views = mSolo.getViews(child); ArrayList imageViews = new ArrayList(); ArrayList textViews = new ArrayList(); for (int j = 0; j < views.size(); j++) { View v = views.get(j); if (v instanceof TextView) { TextView t = (TextView)v; textViews.add(t); String string = t.getText().toString(); mAsserter.ok(!TextUtils.isEmpty(string), "TextView is filled in", string); } else if (v instanceof ImageView) { imageViews.add((ImageView)v); } } int visible = 0; for (int j = 0; j < imageViews.size(); j++) { ImageView img = imageViews.get(j); visible += (img.getVisibility() == View.VISIBLE) ? 1 : 0; } mAsserter.is(visible, numImageViews, "Correct number of ImageViews visible"); visible = 0; for (int j = 0; j < textViews.size(); j++) { TextView text = textViews.get(j); visible += (text.getVisibility() == View.VISIBLE) ? 1 : 0; } mAsserter.is(textViews.size(), numTextViews, "Correct number of TextViews visible"); } @Override public void tearDown() throws Exception { deleteBookmark("BOOKMARK_TITLE"); super.tearDown(); } }