/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.google.gdt.eclipse.swtbot;
import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.widgetOfType;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.finders.ContextMenuHelper;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
/**
* SWTBot utility methods that perform general workbench actions.
*/
public final class SwtBotProjectActions {
/**
* Possible names for the GWT menu label.
*/
public static final String[] GWT_MENU_LABELS = {"GWT"};
private static final String SOURCE_FOLDER = "src";
/**
* Creates a java class with the specified name.
*
* @param bot The SWTWorkbenchBot.
* @param projectName The name of the project the class should be created in.
* @param packageName The name of the package the class should be created in.
* @param className The name of the java class to be created.
*/
public static void createJavaClass(final SWTWorkbenchBot bot, String projectName,
String packageName, final String className) {
SWTBotTreeItem project = SwtBotProjectActions.selectProject(bot, projectName);
selectProjectItem(project, SOURCE_FOLDER, packageName).select();
SwtBotUtils.performAndWaitForWindowChange(bot, new Runnable() {
@Override
public void run() {
MenuItem menuItem = ContextMenuHelper.contextMenu(getProjectRootTree(bot), "New", "Class");
new SWTBotMenu(menuItem).click();
}
});
SwtBotUtils.performAndWaitForWindowChange(bot, new Runnable() {
@Override
public void run() {
bot.activeShell();
bot.textWithLabel("Name:").setText(className);
SwtBotUtils.clickButtonAndWaitForWindowChange(bot, bot.button("Finish"));
}
});
}
/**
* Creates a java project with the specified project name.
*
* @param bot the SWTWorkbenchBot
* @param projectName the name of the java project to create
*/
public static void createJavaProject(SWTWorkbenchBot bot, String projectName) {
// Open Java Perspective
bot.perspectiveById("org.eclipse.jdt.ui.JavaPerspective").activate();
// Open the list of new project wizards
bot.menu("File").menu("New").menu("Project...").click();
// Select the Java project
SWTBotTree projectSelectionTree = bot.tree();
SWTBotTreeItem projectSelectionGoogleTreeItem =
SwtBotTreeActions.getUniqueTreeItem(bot, projectSelectionTree, "Java", "Java Project");
SwtBotTreeActions.selectTreeItem(bot, projectSelectionGoogleTreeItem, "Java Project");
bot.button("Next >").click();
// Configure the project and then create it
bot.textWithLabel("Project name:").setText(projectName);
SwtBotUtils.clickButtonAndWaitForWindowChange(bot, bot.button("Finish"));
}
/**
* Create a Maven project from Archetype and land in the Java perspective.
*/
public static void createMavenProjectFromArchetype(final SWTWorkbenchBot bot, String groupId,
String artifactId, String packageName, String archetypeGroupId, String archetypeArtifactId,
String archetypeVersion, String archetypeUrl) {
// create maven project
SwtBotMenuActions.openNewMavenProject(bot);
// move to next step, archetype selection
bot.button("Next >").click();
// include snapshot archetypes checkbox
bot.checkBox(1).click();
// open archetype dialog
SwtBotUtils.performAndWaitForWindowChange(bot, new Runnable() {
@Override
public void run() {
bot.button("Add Archetype...").click();
}
});
// Dialog: "New Maven Project"
// The Archetype project source lives here
// Generated with this repos generator
bot.comboBox(0).setText(archetypeGroupId);
bot.comboBox(1).setText(archetypeArtifactId);
bot.comboBox(2).setText(archetypeVersion);
bot.comboBox(3).setText(archetypeUrl);
// close archetype dialog
SwtBotUtils.performAndWaitForWindowChange(bot, new Runnable() {
@Override
public void run() {
// After OK, it will take a minute to download
bot.button("OK").click();
}
});
// filter so only one row shows up
bot.text().setText(archetypeArtifactId);
// select first row
SWTBotTable table = bot.table();
table.setFocus();
table.getTableItem(0).select();
// move to last wizard
bot.button("Next >").click();
// set archetype inputs
bot.comboBox(0).setText(groupId);
bot.comboBox(1).setText(artifactId);
bot.comboBox(3).setText(packageName);
// finish and close dialog, and it will init
bot.button("Finish").click();
// change to the java perpective for next stage
SwtBotMenuActions.openJavaPerpsective(bot);
// select the first project
bot.tree().setFocus();
}
public static void createUiBinder(final SWTWorkbenchBot bot, String projectName,
String packageName, String name, boolean generateSampleContent, boolean generateComments) {
// Open the list of new project wizards
bot.menu("File").menu("New").menu("Other...").click();
// Select the Web App project wizard
SWTBotTree projectSelectionTree = bot.tree();
SWTBotTreeItem projectSelectionGoogleTreeItem = SwtBotTreeActions
.getUniqueTreeItem(bot, projectSelectionTree, "GWT Classes", "UiBinder").expand();
SwtBotTreeActions.selectTreeItem(bot, projectSelectionGoogleTreeItem, "UiBinder");
bot.button("Next >").click();
// Configure the UiBinder and then create it
String sourceFolder = projectName + "/" + SOURCE_FOLDER;
bot.textWithLabel("Source folder:").setText(sourceFolder);
bot.textWithLabel("Package:").setText(packageName);
bot.textWithLabel("Name:").setText(name);
SwtBotUtils.setCheckBox(bot.checkBox("Generate sample content"),
generateSampleContent);
SwtBotUtils.setCheckBox(bot.checkBox("Generate comments"), generateComments);
SwtBotUtils.clickButtonAndWaitForWindowChange(bot, bot.button("Finish"));
}
public static void createWebAppProject(final SWTWorkbenchBot bot, String projectName,
String packageName, boolean useGwt, boolean generateSampleCode) {
// Open Java Perspective
bot.perspectiveById("org.eclipse.jdt.ui.JavaPerspective").activate();
// Open the list of new project wizards
bot.menu("File").menu("New").menu("Project...").click();
// Select the Web App project wizard
SWTBotTree projectSelectionTree = bot.tree();
// GWT Application
SWTBotTreeItem projectSelectionTreeItem = SwtBotTreeActions.getUniqueTreeItem(bot,
projectSelectionTree, "GWT Application", "GWT Web Application Project").expand();
SwtBotTreeActions.selectTreeItem(bot, projectSelectionTreeItem,
"GWT Web Application Project");
bot.button("Next >").click();
// Configure the project and then create it
bot.textWithLabel("Project name:").setText(projectName);
bot.textWithLabel("Package: (e.g. com.example.myproject)").setText(packageName);
SwtBotUtils.setCheckBox(bot.checkBox("Use GWT"), useGwt);
SwtBotUtils.setCheckBox(bot.checkBox("Generate project sample code"),
generateSampleCode);
SwtBotUtils.clickButtonAndWaitForWindowChange(bot, bot.button("Finish"));
SwtBotWorkbenchActions.waitForIdle(bot);
}
public static void deleteProject(final SWTWorkbenchBot bot, final String projectName) {
SwtBotUtils.print("Deleting project " + projectName);
// delete the launch configs created
deleteLaunchConfigs(bot);
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
try {
project.delete(true, null);
} catch (CoreException e) {
SwtBotUtils.printError("Could not delete project");
}
SwtBotWorkbenchActions.waitForIdle(bot);
SwtBotUtils.print("Deleted project " + projectName);
}
public static void deleteLaunchConfigs(final SWTWorkbenchBot bot) {
SwtBotUtils.print("\tDeleting launch configs");
SwtBotLaunchManagerActions.terminateAllLaunchConfigs(bot);
SwtBotMenuActions.openDebugConfiguration(bot);
// TODO change to Messages.get
SWTBotTreeItem subTree = bot.tree(0).getTreeItem("GWT Development Mode (DevMode)");
subTree.expand();
SWTBotTreeItem[] items = subTree.getItems();
if (items != null && items.length > 0) {
for (int i=0; i < items.length; i++) {
SwtBotUtils.print("\t\tDeleting launcher i=" + i);
items[i].contextMenu("Delete").click();
SwtBotUtils.performAndWaitForWindowChange(bot, new Runnable() {
@Override
public void run() {
bot.button("Yes").click();
}
});
bot.sleep(500);
}
}
bot.button("Close").click();
SwtBotUtils.print("\tDeleted launch configs");
}
/**
* Returns true if the specified project can be found in the 'Package Explorer' or 'Project View',
* otherwise returns false. Throws a WidgetNotFoundException exception if the 'Package Explorer'
* or 'Project Explorer' view cannot be found.
*
* @param bot The SWTWorkbenchBot.
* @param projectName The name of the project to be found.
* @return if the project exists
*/
public static boolean doesProjectExist(final SWTWorkbenchBot bot, String projectName) {
SWTBotView explorer = getPackageExplorer(bot);
if (explorer == null) {
throw new WidgetNotFoundException(
"Could not find the 'Package Explorer' or 'Project Explorer' view.");
}
// Select the root of the project tree in the explorer view
Widget explorerWidget = explorer.getWidget();
Tree explorerTree = bot.widget(widgetOfType(Tree.class), explorerWidget);
SWTBotTreeItem[] allItems = new SWTBotTree(explorerTree).getAllItems();
for (int i = 0; i < allItems.length; i++) {
if (allItems[i].getText().equals(projectName)) {
return true;
}
}
return false;
}
/*
* Choose either the Package Explorer View or the Project Explorer view. Eclipse 3.3 and 3.4 start
* with the Java Perspective, which has the Package Explorer View open by default, whereas Eclipse
* 3.5 starts with the Resource Perspective, which has the Project Explorer View open.
*/
public static SWTBotView getPackageExplorer(final SWTWorkbenchBot bot) {
SWTBotView explorer = null;
for (SWTBotView view : bot.views()) {
if (view.getTitle().equals("Package Explorer")
|| view.getTitle().equals("Project Explorer")) {
explorer = view;
break;
}
}
return explorer;
}
/**
* Returns the project root tree in Package Explorer.
*/
public static SWTBotTree getProjectRootTree(SWTWorkbenchBot bot) {
SWTBotView explorer = getPackageExplorer(bot);
if (explorer == null) {
throw new WidgetNotFoundException("Cannot find Package Explorer or Project Explorer");
}
Tree tree = bot.widget(widgetOfType(Tree.class), explorer.getWidget());
return new SWTBotTree(tree);
}
/**
* Returns true if there are errors in the Problem view. Returns false otherwise.
*/
public static boolean hasErrorsInProblemsView(SWTWorkbenchBot bot) {
// Open Problems View by Window -> show view -> Problems
bot.menu("Window").menu("Show View").menu("Problems").click();
SWTBotView view = bot.viewByTitle("Problems");
view.show();
SWTBotTree tree = view.bot().tree();
for (SWTBotTreeItem item : tree.getAllItems()) {
String text = item.getText();
if (text != null && text.startsWith("Errors")) {
return true;
}
}
return false;
}
/**
* Opens the Properties dialog for a given project.
*
* This method assumes that either the Package Explorer or Project Explorer view is visible.
*/
public static void openProjectProperties(final SWTWorkbenchBot bot, String projectName) {
selectProject(bot, projectName);
SwtBotUtils.performAndWaitForWindowChange(bot, new Runnable() {
@Override
public void run() {
// Open the Project Properties menu via the File menu
SWTBotMenu fileMenu = bot.menu("File");
fileMenu.menu("Properties").click();
}
});
}
/**
* Refresh project tree.
*
* @param bot The SWTWorkbenchBot.
* @param projectName The project name.
*/
public static void refreshProject(final SWTWorkbenchBot bot, String projectName) {
SWTBotTreeItem project = selectProject(bot, projectName);
project.contextMenu("Refresh").click();
}
/**
* Returns the specified project. Throws a WidgetNotFoundException if the 'Package Explorer' or
* 'Project Explorer' view cannot be found or if the specified project cannot be found.
*
* @param bot The SWTWorkbenchBot.
* @param projectName The name of the project to select.
* @return the tree
*/
public static SWTBotTreeItem selectProject(final SWTWorkbenchBot bot, String projectName) {
/*
* Choose either the Package Explorer View or the Project Explorer view. Eclipse 3.3 and 3.4
* start with the Java Perspective, which has the Package Explorer View open by default, whereas
* Eclipse 3.5 starts with the Resource Perspective, which has the Project Explorer View open.
*/
SWTBotView explorer = getPackageExplorer(bot);
for (SWTBotView view : bot.views()) {
if (view.getTitle().equals("Package Explorer")
|| view.getTitle().equals("Project Explorer")) {
explorer = view;
break;
}
}
if (explorer == null) {
throw new WidgetNotFoundException(
"Could not find the 'Package Explorer' or 'Project Explorer' view.");
}
// Select the root of the project tree in the explorer view
Widget explorerWidget = explorer.getWidget();
Tree explorerTree = bot.widget(widgetOfType(Tree.class), explorerWidget);
return new SWTBotTree(explorerTree).getTreeItem(projectName).select();
}
/**
* Select a file/folder by providing a parent tree, and a list folders that lead to the
* file/folder.
*
* @param item Root tree item.
* @param folderPath List of folder names that lead to file.
* @return Returns a SWTBotTreeItem of the last name in texts.
*/
public static SWTBotTreeItem selectProjectItem(SWTBotTreeItem item, String... folderPath) {
for (String folder : folderPath) {
if (item == null) {
return null;
}
item.doubleClick();
item = item.getNode(folder);
}
return item;
}
private SwtBotProjectActions() {}
}