/** * Copyright (c) 2015 Pawel Nowak. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Based on https://github.com/eclipse/cdt/blob/master/build/org.eclipse.cdt.autotools.ui.tests/src/org/eclipse/cdt/autotools/ui/tests/AbstractTest.java */ package org.eclipse.recommenders.internal.news.rcp.preferences; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; import java.text.MessageFormat; import org.eclipse.recommenders.internal.news.rcp.Constants; import org.eclipse.recommenders.internal.news.rcp.l10n.Messages; import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException; import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; import org.eclipse.swtbot.swt.finder.waits.DefaultCondition; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PreferencesUtil; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import com.google.common.base.Joiner; @RunWith(SWTBotJunit4ClassRunner.class) public class NewsPreferencePageUITest { private static final String VALID_FEED_NAME = "feed"; //$NON-NLS-1$ private static final String VALID_FEED_NAME_A = "feedA"; //$NON-NLS-1$ private static final String VALID_FEED_URL = "http://eclipse.org"; //$NON-NLS-1$ private static final String INVALID_FEED_URL = "http://ยง$%"; //$NON-NLS-1$ private static final String CHARACTERS_AND_DIGITS = "abc123"; //$NON-NLS-1$ private static final String INVALID_FEED_PROTOCOL = "ftp://eclipse.org"; //$NON-NLS-1$ private SWTWorkbenchBot bot; @Before public void setUp() { bot = new SWTWorkbenchBot(); openPreferencePage(bot); } @After public void tearDown() { if (!bot.activeShell().getText().equals("Preferences")) { //$NON-NLS-1$ bot.button("Cancel").click(); //$NON-NLS-1$ } bot.button("Restore Defaults").click(); //$NON-NLS-1$ bot.button("OK").click(); //$NON-NLS-1$ } @Test public void testAddCustomFeed() { addCustomFeed(bot); applyChangesAndReopenPreferencePage(); assertThat(bot.table().getTableItem(1).getText(), is(equalTo(VALID_FEED_NAME))); } @Test public void testAddCustomFeedWithoutName() { bot.button(Messages.PREFPAGE_BUTTON_NEW).click(); bot.textWithLabel(Messages.FIELD_LABEL_URL).setText(VALID_FEED_URL); // the space below is here because TitleAreaDialog also adds a space to messages assertThat(bot.text(" " + Messages.FEED_DIALOG_ERROR_EMPTY_NAME), is(notNullValue())); //$NON-NLS-1$ assertThat(bot.button("OK").isEnabled(), is(false)); //$NON-NLS-1$ } @Test public void testAddCustomFeedWithoutURL() { bot.button(Messages.PREFPAGE_BUTTON_NEW).click(); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME); assertThat(bot.text(" " + Messages.FEED_DIALOG_ERROR_EMPTY_URL), is(notNullValue())); //$NON-NLS-1$ assertThat(bot.button("OK").isEnabled(), is(false)); //$NON-NLS-1$ } @Test public void testAddCustomFeedWithInvalidURL() { bot.button(Messages.PREFPAGE_BUTTON_NEW).click(); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME); bot.textWithLabel(Messages.FIELD_LABEL_URL).setText(INVALID_FEED_URL); assertThat(bot.text(" " + Messages.FEED_DIALOG_ERROR_INVALID_URL), is(notNullValue())); //$NON-NLS-1$ assertThat(bot.button("OK").isEnabled(), is(false)); //$NON-NLS-1$ } @Test public void testAddCustomFeedWithInvalidPollingInterval() { bot.button(Messages.PREFPAGE_BUTTON_NEW).click(); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME); bot.textWithLabel(Messages.FIELD_LABEL_URL).setText(VALID_FEED_URL); bot.textWithLabel(Messages.FIELD_LABEL_POLLING_INTERVAL).setText(CHARACTERS_AND_DIGITS); assertThat(bot.text(" " + Messages.FEED_DIALOG_ERROR_POLLING_INTERVAL_INVALID), is(notNullValue())); //$NON-NLS-1$ assertThat(bot.button("OK").isEnabled(), is(false)); //$NON-NLS-1$ } @Test public void testAddCustomFeedWithDuplicateURL() { bot.button(Messages.PREFPAGE_BUTTON_NEW).click(); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME); bot.textWithLabel(Messages.FIELD_LABEL_URL).setText("http://planeteclipse.org/planet/rss20.xml"); //$NON-NLS-1$ assertThat(bot.text(" " + MessageFormat.format(Messages.FEED_DIALOG_ERROR_DUPLICATE_FEED, "Planet Eclipse")), //$NON-NLS-1$ //$NON-NLS-2$ is(notNullValue())); assertThat(bot.button("OK").isEnabled(), is(false)); //$NON-NLS-1$ } @Test public void testAddCustomFeedWithInvalidProtocol() { bot.button(Messages.PREFPAGE_BUTTON_NEW).click(); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME); bot.textWithLabel(Messages.FIELD_LABEL_URL).setText(INVALID_FEED_PROTOCOL); assertThat( bot.text(" " + MessageFormat.format(Messages.FEED_DIALOG_ERROR_PROTOCOL_UNSUPPORTED, INVALID_FEED_PROTOCOL, Joiner.on(", ").join(FeedDialog.ACCEPTED_PROTOCOLS))), is(notNullValue())); assertThat(bot.button("OK").isEnabled(), is(false)); //$NON-NLS-1$ } @Test public void testRemoveCustomFeed() { addCustomFeed(bot); bot.table().getTableItem(1).select(); bot.button(Messages.PREFPAGE_BUTTON_REMOVE).click(); applyChangesAndReopenPreferencePage(); assertThat(bot.table().rowCount(), is(equalTo(2))); } @Test public void testEditCustomFeed() { addCustomFeed(bot); bot.table().getTableItem(1).select(); bot.button(Messages.PREFPAGE_BUTTON_EDIT).click(); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME_A); bot.button("OK").click(); applyChangesAndReopenPreferencePage(); assertThat(bot.table().rowCount(), is(equalTo(3))); assertThat(bot.table().getTableItem(1).getText(), is(equalTo(VALID_FEED_NAME_A))); } @Test public void testEditCustomFeedByDoubleClick() { addCustomFeed(bot); bot.table().doubleClick(1, 0); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME_A); bot.button("OK").click(); applyChangesAndReopenPreferencePage(); assertThat(bot.table().rowCount(), is(equalTo(3))); assertThat(bot.table().getTableItem(1).getText(), is(equalTo(VALID_FEED_NAME_A))); } @Test public void testCannotEditDefaultFeed() { bot.table().doubleClick(1, 0); bot.activeShell().activate(); // the shell will be still Preferences, because it's not possible to edit default repository feed, so the dialog // won't be opened assertThat(bot.activeShell().getText(), is(equalTo("Preferences"))); //$NON-NLS-1$ assertThat(bot.button(Messages.PREFPAGE_BUTTON_EDIT).isEnabled(), is(false)); } @Test public void testDisableNewsFeed() { bot.checkBox(Messages.FIELD_LABEL_NEWS_ENABLED).click(); applyChangesAndReopenPreferencePage(); assertThat(bot.checkBox(Messages.FIELD_LABEL_NEWS_ENABLED).isChecked(), is(false)); } @Test public void testDisableCustomFeed() { addCustomFeed(bot); bot.table().getTableItem(2).uncheck(); applyChangesAndReopenPreferencePage(); assertThat(bot.table().getTableItem(2).isChecked(), is(false)); } @Test public void testDisableDefaultRepositoryFeed() { bot.table().getTableItem(0).uncheck(); applyChangesAndReopenPreferencePage(); assertThat(bot.table().getTableItem(0).isChecked(), is(false)); } @Test public void testRestoreDefaults() { addCustomFeed(bot); applyChangesAndReopenPreferencePage(); bot.button("Restore Defaults").click(); //$NON-NLS-1$ applyChangesAndReopenPreferencePage(); assertThat(bot.table().rowCount(), is(equalTo(2))); } @Ignore("this test fails on Hudson CI for unkown reason, proably the pages are elsewhere since this test is version dependent") @Test public void testNotificationLinkLeadsToProperPreferencePage() { bot.link().click("Notifications"); SWTBotTreeItem treeGeneral = bot.tree().getTreeItem("General"); SWTBotTreeItem treeNotifications = treeGeneral.getNode("Notifications"); assertThat(treeNotifications.isSelected(), is(true)); } @Ignore("this test fails on Hudson CI for unkown reason, proably the pages are elsewhere since this test is version dependent") @Test public void testBrowserLinkLeadsToProperPreferencePage() { bot.link(1).click("Web Browser"); SWTBotTreeItem treeGeneral = bot.tree().getTreeItem("General"); SWTBotTreeItem treeWebBrowser = treeGeneral.getNode("Web Browser"); assertThat(treeWebBrowser.isSelected(), is(true)); } @Test public void testFeedProvidedByExtensionPointContainsContributedBySuffix() { assertThat(bot.table().getTableItem(0).getText(), containsString("(contributed ")); } private static void openPreferencePage(SWTWorkbenchBot bot) { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { PreferencesUtil .createPreferenceDialogOn(null, Constants.PREF_PAGE_ID, null, null) .open(); } }); bot.waitUntil(new NodeAvailableAndSelect(bot.tree(), "General", Messages.PREFPAGE_TITLE)); //$NON-NLS-1$ } private void applyChangesAndReopenPreferencePage() { bot.button("OK").click(); openPreferencePage(bot); } private void addCustomFeed(SWTWorkbenchBot bot) { bot.button(Messages.PREFPAGE_BUTTON_NEW).click(); bot.textWithLabel(Messages.FIELD_LABEL_FEED_NAME).setText(VALID_FEED_NAME); bot.textWithLabel(Messages.FIELD_LABEL_URL).setText(VALID_FEED_URL); bot.button("OK").click(); } public static class NodeAvailableAndSelect extends DefaultCondition { private final SWTBotTree tree; private final String parent; private final String node; /** * Wait for a tree node (with a known parent) to become visible, and select it when it does. Note that this wait * condition should only be used after having made an attempt to reveal the node. * * @param tree * The SWTBotTree that contains the node to select. * @param parent * The text of the parent node that contains the node to select. * @param node * The text of the node to select. */ public NodeAvailableAndSelect(SWTBotTree tree, String parent, String node) { this.tree = tree; this.node = node; this.parent = parent; } @Override public boolean test() { try { SWTBotTreeItem parentNode = tree.getTreeItem(parent); parentNode.getNode(node).select(); return true; } catch (WidgetNotFoundException e) { return false; } } @Override public String getFailureMessage() { return "Timed out waiting for " + node; //$NON-NLS-1$ } } }