diff --git a/dev/org.eclipse.codewind.openapi.ui.test/.classpath b/dev/org.eclipse.codewind.openapi.ui.test/.classpath
new file mode 100644
index 0000000..3e5654f
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/.gitignore b/dev/org.eclipse.codewind.openapi.ui.test/.gitignore
new file mode 100644
index 0000000..ca9f8b7
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/.gitignore
@@ -0,0 +1,3 @@
+*.class
+/bin
+/build
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/.project b/dev/org.eclipse.codewind.openapi.ui.test/.project
new file mode 100644
index 0000000..0d65e2c
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/.project
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.codewind.openapi.ui.test
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/.settings/org.eclipse.jdt.core.prefs b/dev/org.eclipse.codewind.openapi.ui.test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/META-INF/MANIFEST.MF b/dev/org.eclipse.codewind.openapi.ui.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..50835e0
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: OpenAPI UI Test Plugin
+Bundle-SymbolicName: org.eclipse.codewind.openapi.ui.test
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.codewind.openapi.ui.test.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.swtbot.eclipse.finder,
+ org.eclipse.swtbot.junit4_x,
+ org.junit,
+ org.eclipse.ui.ide,
+ org.eclipse.core.resources,
+ org.eclipse.codewind.openapi.test
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Automatic-Module-Name: org.eclipse.codewind.openapi.ui.test
+Bundle-ActivationPolicy: lazy
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/build.properties b/dev/org.eclipse.codewind.openapi.ui.test/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/Activator.java b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/Activator.java
new file mode 100644
index 0000000..4d538f4
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/Activator.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.codewind.openapi.ui.test;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.codewind.openapi.ui.test"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/AllUiTests.java b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/AllUiTests.java
new file mode 100644
index 0000000..982b82c
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/AllUiTests.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.codewind.openapi.ui.test;
+
+import org.eclipse.codewind.openapi.ui.test.menus.ContextMenuTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ ContextMenuTest.class
+})
+public class AllUiTests {
+
+ public AllUiTests() {
+ // Empty
+ }
+
+}
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/BaseTestCase.java b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/BaseTestCase.java
new file mode 100644
index 0000000..5595c7f
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/BaseTestCase.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.codewind.openapi.ui.test;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import org.eclipse.codewind.openapi.test.Constants;
+import org.eclipse.codewind.openapi.test.util.TestUtilities;
+import org.eclipse.codewind.openapi.ui.test.menus.utils.UITestUtilities;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.SWTBotTestCase;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+public class BaseTestCase extends SWTBotTestCase {
+
+ protected SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
+
+ protected IProject testProject;
+ protected IFile definitionFile;
+
+ // Configurable options to test and should be overridden
+ protected String newProjectName = "TestProject";
+ protected String sourceDefinition = Constants.PETSTORE_30;
+ protected String targetDefinitionInProject = "petstore.yaml";
+
+ public BaseTestCase() {
+ // Empty
+ }
+
+ protected void createGeneralProject(String projectName) {
+ try {
+ this.testProject = TestUtilities.createGeneralProject(projectName);
+ } catch (CoreException e) {
+ fail();
+ }
+ assertNotNull("Project creation", this.testProject);
+ assertEquals("Test project name", projectName, this.testProject.getName());
+ }
+
+ /**
+ *
+ * @param sourceFile - source OpenAPI definition in the test plugin resources folder
+ * @param destinationFile - path of target OpenAPI definition in the test project but excludes
+ * the project name
+ */
+ protected void copyDefinitionToProject(String sourceFile, String destinationFile) {
+ try {
+ this.definitionFile = TestUtilities.copyDefinitionToProject(sourceFile, destinationFile, this.testProject);
+ assertTrue("Copied file exists in workspace", this.definitionFile.exists());
+ assertEquals("Definition is in the test project", this.testProject, this.definitionFile.getProject());
+ } catch (CoreException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ protected void setup() {
+ createGeneralProject(this.newProjectName);
+ copyDefinitionToProject(this.sourceDefinition, this.targetDefinitionInProject);
+ }
+
+ protected void doTestInProjectExplorer(boolean openApiMenuShouldAppear) {
+ SWTBotView view = UITestUtilities.getProjectExplorerView();
+ StringTokenizer token = new StringTokenizer(targetDefinitionInProject, "/");
+ Stack pathSegments = new Stack();
+ while (token.hasMoreElements()) {
+ pathSegments.add(0, token.nextToken());
+ }
+ verifyContextMenu(openApiMenuShouldAppear, view, newProjectName, pathSegments);
+ }
+
+ // Accept first child node of root node
+ protected void verifyContextMenu(boolean expectedOpenApiMenuExists, SWTBotView view, String rootNode, Stack pathSegments) {
+ SWTBotTreeItem targetTreeItem = UITestUtilities.findTreeItem(rootNode, view, pathSegments);
+ verifyContextMenu(expectedOpenApiMenuExists, targetTreeItem);
+ }
+
+ // Accept a path to the child node relative to the root node
+ protected void verifyContextMenu(boolean expectedOpenApiMenuExists, SWTBotView view, String rootNode, String childNode) {
+ SWTBotTreeItem targetTreeItem = UITestUtilities.findTreeItem(rootNode, view, childNode);
+ verifyContextMenu(expectedOpenApiMenuExists, targetTreeItem);
+ }
+
+ private void verifyContextMenu(boolean expectedOpenApiMenuExists, SWTBotTreeItem targetTreeItem) {
+ assertNotNull("The test file should be in the project and the tree node exists", targetTreeItem);
+ try {
+ SWTBotMenu contextMenu = targetTreeItem.contextMenu(UIConstants.MENU_OPENAPI_GENERATE);
+ if (expectedOpenApiMenuExists) {
+ assertNotNull("OpenAPI Generate menu should exist", contextMenu);
+ List cascadeMenuItems = contextMenu.menuItems();
+ for (String s: cascadeMenuItems) {
+ System.out.println(s);
+ }
+ assertTrue("There should be three menu actions", cascadeMenuItems.size() == 3);
+ assertTrue("Client API stub... menu exists", cascadeMenuItems.get(0).equals(UIConstants.MENU_GEN_CLIENT));
+ assertTrue("Server API stub... menu exists", cascadeMenuItems.get(1).equals(UIConstants.MENU_GEN_SERVER));
+ assertTrue("HTML documentation...", cascadeMenuItems.get(2).equals(UIConstants.MENU_HTML));
+ }
+ } catch (Exception e) {
+ if (!expectedOpenApiMenuExists) {
+ assertTrue("OpenAPI Generate menu should not be available on non-OpenAPI 3.0 documents", e instanceof WidgetNotFoundException);
+ return;
+ }
+ throw e; // Fail test if test otherwise
+ }
+ }
+}
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/UIConstants.java b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/UIConstants.java
new file mode 100644
index 0000000..9b1f5a6
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/UIConstants.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.codewind.openapi.ui.test;
+
+public class UIConstants {
+
+ public UIConstants() {
+ // Empty
+ }
+
+ // The following four strings are hard coded into the org.eclipse.codewind.openapi.ui plugin.properties
+ public static String MENU_OPENAPI_GENERATE = "OpenAPI Generate";
+ public static String MENU_GEN_CLIENT = "Client API stub...";
+ public static String MENU_GEN_SERVER = "Server API stub...";
+ public static String MENU_HTML = "HTML documentation...";
+}
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/menus/ContextMenuTest.java b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/menus/ContextMenuTest.java
new file mode 100644
index 0000000..649c6fc
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/menus/ContextMenuTest.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.codewind.openapi.ui.test.menus;
+
+import org.eclipse.codewind.openapi.test.Constants;
+import org.eclipse.codewind.openapi.ui.test.BaseTestCase;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.junit.runners.MethodSorters;
+
+@RunWith(JUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class ContextMenuTest extends BaseTestCase {
+
+ public ContextMenuTest() {
+ this.newProjectName = "TestProject";
+ }
+
+ @BeforeClass
+ public static void beforeClass() {
+ SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
+ swtWorkbenchBot.viewByTitle("Welcome").close();
+ }
+
+ @Test
+ public void testContextMenu01() {
+ sourceDefinition = Constants.PETSTORE_30;
+ targetDefinitionInProject = "petstore.yaml";
+ setup();
+ doTestInProjectExplorer(true);
+ }
+
+ @Test
+ public void testContextMenu02() {
+ sourceDefinition = Constants.GEN_JSON_30;
+ targetDefinitionInProject = Constants.GEN_JSON_30;
+ setup();
+ doTestInProjectExplorer(true);
+ }
+
+ @Test
+ public void testContextMenu03() {
+ sourceDefinition = Constants.GEN_YAML_30;
+ targetDefinitionInProject = Constants.GEN_YAML_30;
+ setup();
+ doTestInProjectExplorer(true);
+ }
+
+ @Test
+ public void testContextMenu04() {
+ sourceDefinition = Constants.GEN_YML_30;
+ targetDefinitionInProject = Constants.GEN_YML_30;
+ setup();
+ doTestInProjectExplorer(true);
+ }
+
+ @Test
+ public void testContextMenu05() {
+ sourceDefinition = Constants.PETSTORE_OAS_30;
+ targetDefinitionInProject = Constants.PETSTORE_OAS_30;
+ setup();
+ doTestInProjectExplorer(true);
+ }
+
+ @Test
+ public void testContextMenu06() {
+ sourceDefinition = Constants.PETSTORE_JSON_30;
+ targetDefinitionInProject = Constants.PETSTORE_JSON_30;
+ setup();
+ doTestInProjectExplorer(true);
+ }
+
+ @Test
+ public void testContextMenu07() {
+ sourceDefinition = Constants.SWAGGER_JSON_30;
+ targetDefinitionInProject = Constants.SWAGGER_JSON_30;
+ setup();
+ doTestInProjectExplorer(true);
+ }
+
+ // Non OpenAPI 3.0 documents including Swagger 2.0 documents
+
+ @Test
+ public void testForNoContextMenu01() {
+ sourceDefinition = Constants.SWAGGER_JSON_20;
+ targetDefinitionInProject = Constants.SWAGGER_JSON_20;
+ setup();
+ doTestInProjectExplorer(false);
+ }
+
+ @Test
+ public void testForNoContextMenu02() {
+ sourceDefinition = Constants.SWAGGER_YAML_20;
+ targetDefinitionInProject = Constants.SWAGGER_YAML_20;
+ setup();
+ doTestInProjectExplorer(false);
+ }
+
+ @Test
+ public void testForNoContextMenu03() {
+ sourceDefinition = Constants.SWAGGER001_YAML_20;
+ targetDefinitionInProject = Constants.SWAGGER001_YAML_20;
+ setup();
+ doTestInProjectExplorer(false);
+ }
+
+ @Test
+ public void testForNoContextMenu04() {
+ sourceDefinition = Constants.SWAGGER002_YAML_20;
+ targetDefinitionInProject = Constants.SWAGGER002_YAML_20;
+ setup();
+ doTestInProjectExplorer(false);
+ }
+
+ @Test
+ public void testForNoContextMenu05() {
+ sourceDefinition = Constants.ANY_JSON_FILE;
+ targetDefinitionInProject = Constants.ANY_JSON_FILE;
+ setup();
+ doTestInProjectExplorer(false);
+ }
+
+ @Test
+ public void testForNoContextMenu06() {
+ sourceDefinition = Constants.ANY_YAML_FILE;
+ targetDefinitionInProject = Constants.ANY_YAML_FILE;
+ setup();
+ doTestInProjectExplorer(false);
+ }
+
+ @Test
+ public void testForNoContextMenu07() {
+ sourceDefinition = Constants.REGULAR_JSON_FILE;
+ targetDefinitionInProject = Constants.REGULAR_JSON_FILE;
+ setup();
+ doTestInProjectExplorer(false);
+ }
+
+ @After
+ public void deleteTestProject() {
+ IProgressMonitor monitor = new NullProgressMonitor();
+ this.testProject = ResourcesPlugin.getWorkspace().getRoot().getProject(this.newProjectName);
+ try {
+ this.testProject.delete(true, monitor);
+ } catch (CoreException e) {
+ }
+ assertFalse("Project deletion", testProject.exists());
+ }
+}
diff --git a/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/menus/utils/UITestUtilities.java b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/menus/utils/UITestUtilities.java
new file mode 100644
index 0000000..612e8f3
--- /dev/null
+++ b/dev/org.eclipse.codewind.openapi.ui.test/src/org/eclipse/codewind/openapi/ui/test/menus/utils/UITestUtilities.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.codewind.openapi.ui.test.menus.utils;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+import java.util.Stack;
+
+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.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.hamcrest.Matcher;
+
+public class UITestUtilities {
+
+ public UITestUtilities() {
+ // Empty
+ }
+
+ public static SWTBotView getProjectExplorerView() {
+ SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
+ return swtWorkbenchBot.viewById("org.eclipse.ui.navigator.ProjectExplorer");
+ }
+
+ public static SWTBotView getPackageExplorerView() {
+ SWTWorkbenchBot swtWorkbenchBot = new SWTWorkbenchBot();
+ return swtWorkbenchBot.viewById("org.eclipse.jdt.ui.PackageExplorer");
+ }
+
+ /*
+ * Given the specific view, which can have multiple root nodes (eg. multiple projects in the project explorer),
+ * and given the specific root node (rootTreeNode, which is uniquely named amongst other possible root nodes), find the
+ * first child node with the name treeItemText
+ *
+ */
+ public static SWTBotTreeItem findTreeItem(final String rootTreeNode, SWTBotView view, final String treeItemText) {
+ SWTBotTreeItem treeItem = findTreeItemForRoot(rootTreeNode, view);
+ SWTBotTreeItem targetTreeItem = findTargetNode(treeItem, treeItemText);
+ return targetTreeItem;
+ }
+
+ public static SWTBotTreeItem findTreeItem(final String rootTreeNode, SWTBotView view, final Stack pathSegments) {
+ SWTBotTreeItem treeItem = findTreeItemForRoot(rootTreeNode, view);
+ SWTBotTreeItem targetTreeItem = findTargetNode(treeItem, pathSegments);
+ return targetTreeItem;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static SWTBotTreeItem findTreeItemForRoot(final String rootTreeNode, SWTBotView view) {
+ Matcher extends Tree> matcher = WidgetMatcherFactory.allOf(WidgetMatcherFactory.widgetOfType(Tree.class));
+ List extends Widget> widgets = view.bot().widgets(matcher, view.getWidget());
+ SWTBotTree tree = null;
+ SWTBotTreeItem treeItem = null;
+ // Find the root node with the given name rootTreeNode
+ for (Widget o : widgets) {
+ if (o instanceof Tree) {
+ SWTBotTree aTree = new SWTBotTree((Tree) o);
+ SWTBotTreeItem aTreeItem = aTree.getTreeItem(rootTreeNode);
+ if (aTreeItem.getText().equals(rootTreeNode)) {
+ tree = aTree;
+ treeItem = aTreeItem;
+ break;
+ }
+ }
+ }
+ assertNotNull("Expected top level node " + rootTreeNode + " does not exist", tree);
+ tree.expandNode(rootTreeNode, true);
+ return treeItem;
+ }
+
+ private static SWTBotTreeItem findTargetNode(SWTBotTreeItem treeItem, String targetName) {
+ SWTBotTreeItem[] items = treeItem.getItems();
+ for (SWTBotTreeItem aTreeItem : items) {
+ if (!aTreeItem.isEnabled()) {
+ continue;
+ }
+ if (aTreeItem.getText().equals(targetName)) {
+ return aTreeItem;
+ } else {
+ SWTBotTreeItem potential = findTargetNode(aTreeItem, targetName);
+ if (potential != null) {
+ return potential;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static SWTBotTreeItem findTargetNode(SWTBotTreeItem treeItem, Stack pathSegments) {
+ SWTBotTreeItem[] items = treeItem.getItems();
+ for (SWTBotTreeItem aTreeItem : items) {
+ if (!aTreeItem.isEnabled()) {
+ continue;
+ }
+ if (aTreeItem.getText().equals(pathSegments.peek())) {
+ pathSegments.pop();
+ if (pathSegments.isEmpty()) {
+ return aTreeItem;
+ } else {
+ SWTBotTreeItem potential = findTargetNode(aTreeItem, pathSegments);
+ if (potential != null) {
+ return potential;
+ }
+ }
+ } else {
+ SWTBotTreeItem potential = findTargetNode(aTreeItem, pathSegments);
+ if (potential != null) {
+ return potential;
+ }
+ }
+ }
+ return null;
+ }
+}