package swtbot.pageobjects;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
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 uk.ac.ed.csbe.sbsivisual.conditions.ViewOpened;
import uk.ac.ed.csbe.sbsivisual.test.ProjectUtils;
/**
*<p> This class is a wrapper around a Problems View for the purposes of testing.
* It is not particularly intended to be used in testing the Problems View itself, more that
* it provides a way to ensure that markers are being generated and displayed.
*
* <p>This current version assumes that you have a default Problems view grouped by 'Severity'.I.e.,
* the top level items in the view are 'Errors' and 'Warnings'.
*
* <p>Example usage:
* <pre>
*
* // here we create 2 new projects, each with a single application specific error
* ProjectUtils.createStandardProjectWithTestDataAndHeader("TEST",
new File("TestData/ABC_withMissingHeader.sbsidata"),
TestDataUtils.getTestDataHeader(), bot);
ProjectUtils.createStandardProjectWithTestDataAndHeader("TEST2",
new File("TestData/ABC_withMissingHeader.sbsidata"),
TestDataUtils.getTestDataHeader(), bot);
// test set up
final String EXPECTED_WARNING_MESSAGE_FRAGMENT="No header file found";
// open problems view
ProblemsViewPO problemsPO = ProblemsViewPO.openProblemsView(bot);
// wait for all markers to appear in the view after running in a workspace listener.
problemsPO.waitForAtLeastNofType(ProblemsViewPO.WARNINGS, 2);
// check correct warnings are displayed.
assertTrue(problemsPO.getMessage(0, ProblemsViewPO.WARNINGS).contains(EXPECTED_WARNING_MESSAGE_FRAGMENT));
*
* </pre>
*
*
* @author radams
*
*/
public class ProblemsViewPO {
// private constructor used by static factory methods.
private ProblemsViewPO(SWTWorkbenchBot bot) {
super();
this.bot = bot;
}
private final SWTWorkbenchBot bot;
private SWTBotView botView;
public final static String ERROR = "Errors";
public final static String WARNINGS = "Warnings";
/**
* Factory method which opens the Problems view. This method waits for the problem view to
* appear. Assumes the standard Window->Other->Show View mechanism is used and that the
* view is called 'Problems' ( the default name).
*
* @param bot A non-null SWTWorkbenchBot bot.
* @return A {@link ProblemsViewPO} object wrapping a Problems view.
* @throws Timeout exception if the problems view cannot be opened.
*/
public static ProblemsViewPO openProblemsView(final SWTWorkbenchBot bot) {
return openProblemsView(bot, "Problems");
}
/**
* Factory method which opens the Problems view. This method waits for the problem view to
* appear. Assumes the standard Window->Other->Show View mechanism is used.
*
* @param bot A non-null SWTWorkbenchBot bot.
* @param title A <code>String</code> title of the Problems view as it appears in the Window menu.
* @return A {@link ProblemsViewPO} object wrapping a Problems view.
* @throws Timeout exception if the problems view cannot be opened.
*/
public static ProblemsViewPO openProblemsView(final SWTWorkbenchBot bot,
final String title) {
ProblemsViewPO viewPO = new ProblemsViewPO(bot);
viewPO.init(title);
return viewPO;
}
private void init(final String title) {
bot.menu("Window").menu("Other...").click();
bot.shell("Show View").activate();
bot.tree().expandNode("General").expandNode(title).doubleClick();
bot.waitUntil(new ViewOpened(bot, title)); // simple Condition class to test for view
botView = bot.viewByTitle(title);
}
/**
* Getter for underlying SWTBotView of this problems view.
*
* @return the {@link SWTBotView} wrapped by this class. Will not be null if this object
* has initialized properly.
*/
public SWTBotView getBotView() {
return botView;
}
/**
* Getter for number of displayed warnings
*/
public int getDisplayedWarningCount() {
return getCountofType("Warnings");
}
/**
* Getter for number of displayed errors
*/
public int getDisplayedErrorCount() {
return getCountofType("Errors");
}
/**
* Gets the String error/warning message for a problem at a specified index.
* @param rowNumber the index of the warning message.
* @param type
* @return The message, or the empty string if no problems of the spcified type found
* @throws IndexOutOfBoundsException if rowNumber does not exist ( zero -based).
*/
public String getMessage(int rowNumber, String type) {
final int MESSAGE_COLUMN=0;
SWTBotTree tree = botView.bot().tree();
SWTBotTreeItem[] items = tree.getAllItems();
for (SWTBotTreeItem item : items) {
if (item.getText().contains(type)) {
return item.expand().getItems()[rowNumber]
.row().get(MESSAGE_COLUMN);
}
}
return "";
}
/**
* Waits until a given number of errors or warnings are displayed.
* This method is useful if you have modified a resource and want to check the markers
* are updated. Currently this just works for number of displayed markers, rather than all markers.
* This is not a test for an exact number of problems
* @param problemType One of ProblemsViewPO.ERROR or ProblemsViewPO.Warnings
* @param expected An <code> int </code> of the number of expected errors or warnings, >=0
* @throws IllegalArgumentException if <code> expected < 0</code>, or problem type is not a valid String
*/
public void waitForAtLeastNofType (String problemType, int expected) {
if (expected < 0 || (!checkType(problemType))) {
throw new IllegalArgumentException();
}
bot.waitUntil(new NAreGenerated(expected, problemType));
}
private boolean checkType(String problemType) {
return problemType.equals(ProblemsViewPO.ERROR) ||
problemType.equals(ProblemsViewPO.WARNINGS);
}
private int getCountofType(String type) {
SWTBotTree tree = botView.bot().tree();
SWTBotTreeItem[] items = tree.getAllItems();
for (SWTBotTreeItem item : items) {
if (item.getText().contains(type)) {
return item.expand().getItems().length;
}
}
return 0;
}
/*
* Condition class which tests for n warnings or errors being in the P
*/
class NAreGenerated extends DefaultCondition {
private int expected=0;
private String type;
private NAreGenerated(int expected, String type) {
super();
this.expected = expected;
this.type=type;
}
public String getFailureMessage() {
return "Could not find " + expected + " problems of type [" + type + "]";
}
public boolean test() throws Exception {
return getCountofType(type) == expected;
}
}
/**
* General condition that a view with a given title has opened.
*/
public class ViewOpened extends DefaultCondition {
private SWTWorkbenchBot bot;
private String viewTitle;
public ViewOpened(SWTWorkbenchBot bot, String viewTitle) {
this.bot = bot;
this.viewTitle=viewTitle;
}
public String getFailureMessage() {
return "View could not be opened";
}
public boolean test() throws Exception {
return bot.viewByTitle(viewTitle) != null;
}
}
}