Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Johnston2018-03-22 19:57:46 +0000
committerJeff Johnston2018-03-22 19:57:46 +0000
commit1ce1b3df5f3d21d88c80ff9694ceed9b17a0cb1b (patch)
treebd8a3b6e54e01af0f67db7b34799621a14e9a4c6
parent3e60faaa6c65a031c68a279afa80db3306a3f335 (diff)
downloadorg.eclipse.cdt-1ce1b3df5f3d21d88c80ff9694ceed9b17a0cb1b.tar.gz
org.eclipse.cdt-1ce1b3df5f3d21d88c80ff9694ceed9b17a0cb1b.tar.xz
org.eclipse.cdt-1ce1b3df5f3d21d88c80ff9694ceed9b17a0cb1b.zip
Add Meson UI tests plug-in
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/.classpath7
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/.project28
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/META-INF/MANIFEST.MF24
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/about.html24
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/build.properties4
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/pom.xml43
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/AutomatedIntegrationSuite.java20
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/NewMesonProjectTest.java122
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/AbstractSWTBotAssertions.java49
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ButtonAssertions.java28
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CheckBoxAssertions.java46
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseShellRule.java56
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseWelcomePageRule.java72
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ComboAssertions.java53
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ConsoleViewRule.java36
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/MenuAssertion.java46
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ProjectExplorerViewRule.java49
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/RadioAssertion.java46
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotTreeItemAssertions.java68
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotViewRule.java65
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTUtils.java508
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TabDescriptorAssertions.java39
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TestLoggerRule.java26
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TextAssertions.java47
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ToolbarButtonAssertions.java29
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/package-info.java15
-rw-r--r--build/org.eclipse.cdt.meson.ui.tests/swtbot-test-plugin.properties1
28 files changed, 1558 insertions, 0 deletions
diff --git a/build/org.eclipse.cdt.meson.ui.tests/.classpath b/build/org.eclipse.cdt.meson.ui.tests/.classpath
new file mode 100644
index 0000000000..eca7bdba8f
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/build/org.eclipse.cdt.meson.ui.tests/.project b/build/org.eclipse.cdt.meson.ui.tests/.project
new file mode 100644
index 0000000000..3e4a36b937
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.cdt.meson.ui.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/build/org.eclipse.cdt.meson.ui.tests/.settings/org.eclipse.jdt.core.prefs b/build/org.eclipse.cdt.meson.ui.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..0c68a61dca
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/.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/build/org.eclipse.cdt.meson.ui.tests/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.meson.ui.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..38493fc052
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Tests
+Bundle-SymbolicName: org.eclipse.cdt.meson.ui.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.cdt.meson.core;bundle-version="1.0.0",
+ org.eclipse.cdt.meson.ui;bundle-version="1.0.0",
+ org.eclipse.swtbot.junit4_x;bundle-version="2.6.0",
+ org.junit,
+ org.eclipse.cdt.core,
+ org.eclipse.swtbot.eclipse.finder,
+ org.eclipse.core.resources,
+ org.eclipse.core.runtime;bundle-version="3.13.0",
+ org.eclipse.ui;bundle-version="3.109.0",
+ org.apache.log4j;bundle-version="1.2.15",
+ org.eclipse.epp.logging.aeri.core;bundle-version="2.0.7",
+ org.hamcrest.library;bundle-version="1.3.0",
+ org.eclipse.launchbar.ui;bundle-version="2.2.0",
+ org.eclipse.launchbar.ui.controls;bundle-version="1.0.1",
+ org.eclipse.ui.console;bundle-version="3.8.0",
+ org.eclipse.ui.views;bundle-version="3.9.100",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.8.100"
+Import-Package: org.assertj.core.api;version="1.7.1"
diff --git a/build/org.eclipse.cdt.meson.ui.tests/about.html b/build/org.eclipse.cdt.meson.ui.tests/about.html
new file mode 100644
index 0000000000..d7c511887d
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/about.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head>
+
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 22, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body></html> \ No newline at end of file
diff --git a/build/org.eclipse.cdt.meson.ui.tests/build.properties b/build/org.eclipse.cdt.meson.ui.tests/build.properties
new file mode 100644
index 0000000000..34d2e4d2da
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/build/org.eclipse.cdt.meson.ui.tests/pom.xml b/build/org.eclipse.cdt.meson.ui.tests/pom.xml
new file mode 100644
index 0000000000..74639d2bc1
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.cdt</groupId>
+ <artifactId>cdt-parent</artifactId>
+ <version>9.5.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.eclipse.cdt.cmake.ui.tests</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-test-plugin</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <dependency-resolution>
+ <extraRequirements>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.cdt.feature.group</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.cdt.cmake.feature.group</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ </extraRequirements>
+ </dependency-resolution>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/AutomatedIntegrationSuite.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/AutomatedIntegrationSuite.java
new file mode 100644
index 0000000000..966b40d580
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/AutomatedIntegrationSuite.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2017, 2018 QNX Software Systems and others.
+ * 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
+ *
+ * Contributors:
+ * Red Hat Inc. - modified for use in Meson testing
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({ NewMesonProjectTest.class })
+public class AutomatedIntegrationSuite {
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/NewMesonProjectTest.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/NewMesonProjectTest.java
new file mode 100644
index 0000000000..3596726785
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/NewMesonProjectTest.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2017, 2018 QNX Software Systems and others.
+ * 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
+ *
+ * Contributors:
+ * Red Hat Inc. - modified for Meson testing
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests;
+
+import static org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory.withPartName;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.index.IIndexManager;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.internal.meson.ui.tests.utils.CloseWelcomePageRule;
+import org.eclipse.cdt.meson.core.MesonNature;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.epp.logging.aeri.core.ISystemSettings;
+import org.eclipse.epp.logging.aeri.core.SendMode;
+import org.eclipse.epp.logging.aeri.core.SystemControl;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public class NewMesonProjectTest {
+
+ private static SWTWorkbenchBot bot;
+
+ @ClassRule
+ public static CloseWelcomePageRule closeWelcomePage = new CloseWelcomePageRule(
+ CloseWelcomePageRule.CDT_PERSPECTIVE_ID);
+
+ @BeforeClass
+ public static void beforeClass() {
+ SWTBotPreferences.TIMEOUT = 50000;
+ SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
+ bot = new SWTWorkbenchBot();
+ }
+
+ @Before
+ public void before() {
+ ISystemSettings settings = SystemControl.getSystemSettings();
+ settings.setSendMode(SendMode.NEVER);
+ bot.resetWorkbench();
+
+ for (SWTBotView view : bot.views(withPartName("Welcome"))) {
+ view.close();
+ }
+
+ }
+
+ @Test(timeout = 120000)
+ public void createCMakeProject() throws Exception {
+ // open C++ perspective
+ if (!"C/C++".equals(bot.activePerspective().getLabel())) {
+ bot.perspectiveByLabel("C/C++").activate();
+ }
+
+ // Activate C/C++ wizard
+ bot.menu("File").menu("New").menu("C/C++ Project").click();
+ bot.shell("New C/C++ Project").activate();
+
+ // Double click on the template
+ SWTBotTable templateTable = bot.table();
+ bot.getDisplay().syncExec(() -> {
+ for (int i = 0; i < templateTable.rowCount(); ++i) {
+ SWTBotTableItem item = templateTable.getTableItem(i);
+ if ("Meson Project".equals(item.widget.getData(SWTBotPreferences.DEFAULT_KEY))) {
+ item.doubleClick();
+ break;
+ }
+ }
+ });
+
+ // Select the shell again since magic wizardry happened
+ SWTBotShell newProjectShell = bot.shell("New Meson Project").activate();
+
+ // Create the project
+ String projectName = "MesonTestProj";
+ bot.textWithLabel("Project name:").typeText(projectName);
+ bot.button("Finish").click();
+
+ newProjectShell.setFocus();
+ bot.waitUntil(Conditions.shellCloses(newProjectShell));
+
+// return;
+
+// // Make sure it shows up in Project Explorer
+ SWTBotView explorer = bot.viewByPartName("Project Explorer");
+ explorer.show();
+ explorer.setFocus();
+ explorer.bot().tree().getTreeItem(projectName).select();
+
+
+ // Make sure the project indexer completes. At that point we're stable.
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ ICProject cproject = CoreModel.getDefault().create(project);
+ IIndexManager indexManager = CCorePlugin.getIndexManager();
+ while (!indexManager.isProjectContentSynced(cproject)) {
+ Thread.sleep(1000);
+ }
+
+ // Make sure it has the right nature
+ assertTrue(project.hasNature(MesonNature.ID));
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/AbstractSWTBotAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/AbstractSWTBotAssertions.java
new file mode 100644
index 0000000000..4299afb82e
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/AbstractSWTBotAssertions.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.assertj.core.api.AbstractAssert;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+
+/**
+ * Custom assertions on a given {@link AbstractSWTBot} widget
+ * @param <SWTWidget>
+ */
+public abstract class AbstractSWTBotAssertions<Assertion extends AbstractSWTBotAssertions<Assertion, SWTWidget>, SWTWidget extends AbstractSWTBot<?>>
+ extends AbstractAssert<Assertion, SWTWidget> {
+
+ protected AbstractSWTBotAssertions(final SWTWidget actual, final Class<Assertion> clazz) {
+ super(actual, clazz);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Assertion isEnabled() {
+ notNullValue();
+ if(!actual.isEnabled()) {
+ failWithMessage("Expected widget with text '%s (%s)' to be enabled but it was not", actual.getText(),
+ actual.getToolTipText());
+ }
+ return (Assertion) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Assertion isNotEnabled() {
+ notNullValue();
+ if(actual.isEnabled()) {
+ failWithMessage("Expected widget with text '%s (%s)' to be disabled but it was not", actual.getText(),
+ actual.getToolTipText());
+ }
+ return (Assertion) this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ButtonAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ButtonAssertions.java
new file mode 100644
index 0000000000..a960e722a3
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ButtonAssertions.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+
+/**
+ * Custom assertions on a given {@link SWTBotButton}.
+ */
+public class ButtonAssertions extends AbstractSWTBotAssertions<ButtonAssertions, SWTBotButton> {
+
+ protected ButtonAssertions(final SWTBotButton actual) {
+ super(actual, ButtonAssertions.class);
+ }
+
+ public static ButtonAssertions assertThat(final SWTBotButton actual) {
+ return new ButtonAssertions(actual);
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CheckBoxAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CheckBoxAssertions.java
new file mode 100644
index 0000000000..d62d591d79
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CheckBoxAssertions.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox;
+
+/**
+ * Custom assertions on a given {@link SWTBotCheckBox}.
+ */
+public class CheckBoxAssertions extends AbstractSWTBotAssertions<CheckBoxAssertions, SWTBotCheckBox> {
+
+ protected CheckBoxAssertions(final SWTBotCheckBox actual) {
+ super(actual, CheckBoxAssertions.class);
+ }
+
+ public static CheckBoxAssertions assertThat(final SWTBotCheckBox actual) {
+ return new CheckBoxAssertions(actual);
+ }
+
+ public CheckBoxAssertions isChecked() {
+ notNullValue();
+ if(!actual.isChecked()) {
+ failWithMessage("Expected checkbox with text '%s' to be checked but it was not", actual.getText());
+ }
+ return this;
+ }
+
+ public CheckBoxAssertions isNotChecked() {
+ notNullValue();
+ if(actual.isChecked()) {
+ failWithMessage("Expected checkbox with text '%s' to be unchecked but it was not", actual.getText());
+ }
+ return this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseShellRule.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseShellRule.java
new file mode 100644
index 0000000000..8722c89503
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseShellRule.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.ui.PlatformUI;
+import org.junit.rules.ExternalResource;
+
+/**
+ * Closes the wizard(s) after each test, if the "Cancel" button is available
+ */
+public class CloseShellRule extends ExternalResource {
+
+ private final String buttonLabel;
+
+ public CloseShellRule(final String buttonLabel) {
+ this.buttonLabel = buttonLabel;
+ }
+
+ @Override
+ protected void after() {
+ final SWTWorkbenchBot bot = new SWTWorkbenchBot();
+ try {
+ while (isInDialog(bot) && getButton(bot, this.buttonLabel) != null) {
+ getButton(bot, this.buttonLabel).click();
+ }
+
+ } catch (WidgetNotFoundException e) {
+ // ignoring
+ }
+ }
+
+ private static boolean isInDialog(final SWTWorkbenchBot bot) {
+ final SWTBotShell activeShell = bot.activeShell();
+ final String text = SWTUtils
+ .syncExec(() -> PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().getText());
+ final String shellText = activeShell.getText();
+ return text != null && !text.equals(shellText);
+ }
+
+ private static SWTBotButton getButton(final SWTWorkbenchBot bot, final String buttonLabel) {
+ return bot.button(buttonLabel);
+ }
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseWelcomePageRule.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseWelcomePageRule.java
new file mode 100644
index 0000000000..7e2a4341cb
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/CloseWelcomePageRule.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.junit.rules.ExternalResource;
+
+/**
+ * Closes the Welcome page and optionally opens a given perspective
+ */
+public class CloseWelcomePageRule extends ExternalResource {
+
+ public static final String DOCKER_PERSPECTIVE_ID = "org.eclipse.linuxtools.docker.ui.perspective";
+
+ public static final String CDT_PERSPECTIVE_ID = "org.eclipse.cdt.ui.CPerspective";
+
+ public static final String JAVA_PERSPECTIVE_ID = "org.eclipse.jdt.ui.JavaPerspective";
+
+ /** the Id of the perspective to open. */
+ private final String defaultPerspectiveId;
+
+ /**
+ * Custom constructor with the id of the perspective to open once the
+ * welcome page was closed.
+ *
+ * @param perspectiveId
+ * the id of the perspective to open.
+ */
+ public CloseWelcomePageRule(final String perspectiveId) {
+ this.defaultPerspectiveId = perspectiveId;
+ }
+
+ @Override
+ protected void before() {
+ Display.getDefault().syncExec(() -> {
+ final IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench.getIntroManager().getIntro() != null) {
+ workbench.getIntroManager().closeIntro(workbench.getIntroManager().getIntro());
+ }
+ try {
+ workbench.showPerspective(defaultPerspectiveId, workbench.getActiveWorkbenchWindow());
+ } catch (WorkbenchException e) {
+ e.printStackTrace();
+ }
+ });
+ final String PREF_ENABLE_LAUNCHBAR = "enableLaunchBar"; //$NON-NLS-1$
+ final String PREF_ENABLE_TARGETSELECTOR = "enableTargetSelector"; //$NON-NLS-1$
+ final String PREF_ENABLE_BUILDBUTTON = "enableBuildButton"; //$NON-NLS-1$
+
+ Display.getDefault().asyncExec(() -> {
+ final IPreferenceStore store = org.eclipse.launchbar.ui.controls.internal.Activator.getDefault()
+ .getPreferenceStore();
+ store.setValue(PREF_ENABLE_LAUNCHBAR, false);
+ store.setValue(PREF_ENABLE_TARGETSELECTOR, false);
+ store.setValue(PREF_ENABLE_BUILDBUTTON, false);
+ });
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ComboAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ComboAssertions.java
new file mode 100644
index 0000000000..8833194e2b
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ComboAssertions.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo;
+
+/**
+ * Custom assertions on a given {@link SWTBotCheckBox}.
+ */
+public class ComboAssertions extends AbstractSWTBotAssertions<ComboAssertions, SWTBotCombo> {
+
+ protected ComboAssertions(final SWTBotCombo actual) {
+ super(actual, ComboAssertions.class);
+ }
+
+ public static ComboAssertions assertThat(final SWTBotCombo actual) {
+ return new ComboAssertions(actual);
+ }
+
+ public ComboAssertions itemSelected(final String expectedItem) {
+ notNullValue();
+ if (actual.selectionIndex() < 0) {
+ failWithMessage("Expected combo to have selection to '%s' but it had none", expectedItem);
+ } else if (!actual.selection().equals(expectedItem)) {
+ failWithMessage("Expected combo to have selection to '%s' but it was '%s'", expectedItem,
+ actual.selection());
+ }
+ return this;
+ }
+
+ public ComboAssertions indexItemSelected(final int expectedItemIndex) {
+ notNullValue();
+ if (actual.selectionIndex() < 0) {
+ failWithMessage("Expected combo to have selection index to '%s' but it had none", expectedItemIndex);
+ } else if (actual.selectionIndex() != expectedItemIndex) {
+ failWithMessage("Expected combo to have selection index to '%s' but it was '%s'", expectedItemIndex,
+ actual.selectionIndex());
+ }
+ return this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ConsoleViewRule.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ConsoleViewRule.java
new file mode 100644
index 0000000000..203c8b5c73
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ConsoleViewRule.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.junit.rules.ExternalResource;
+
+/**
+ * An {@link ExternalResource} to close the Console view.
+ */
+public class ConsoleViewRule extends ExternalResource {
+
+ @Override
+ protected void before() {
+ Display.getDefault().syncExec(() -> {
+ final SWTBotView consoleView = SWTUtils.getSWTBotView(new SWTWorkbenchBot(),
+ IConsoleConstants.ID_CONSOLE_VIEW);
+ if (consoleView != null) {
+ consoleView.close();
+ }
+ });
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/MenuAssertion.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/MenuAssertion.java
new file mode 100644
index 0000000000..4dafdfedbc
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/MenuAssertion.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 Red Hat Inc.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+
+/**
+ * Custom assertions on a given {@link SWTBotButton}.
+ */
+public class MenuAssertion extends AbstractSWTBotAssertions<MenuAssertion, SWTBotMenu> {
+
+ protected MenuAssertion(final SWTBotMenu actual) {
+ super(actual, MenuAssertion.class);
+ }
+
+ public static MenuAssertion assertThat(final SWTBotMenu actual) {
+ return new MenuAssertion(actual);
+ }
+
+ public MenuAssertion isVisible() {
+ notNullValue();
+ if (!actual.isVisible()) {
+ failWithMessage("Expected menu with text '%s' to be visible but it was not", actual.getText());
+ }
+ return this;
+ }
+
+ public MenuAssertion isNotVisible() {
+ notNullValue();
+ if (actual.isVisible()) {
+ failWithMessage("Expected menu with text '%s' to be visible but it was not", actual.getText());
+ }
+ return this;
+ }
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ProjectExplorerViewRule.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ProjectExplorerViewRule.java
new file mode 100644
index 0000000000..024c4860ab
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ProjectExplorerViewRule.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.junit.Rule;
+import org.junit.rules.ExternalResource;
+
+/**
+ * A JUnit {@link Rule} to open the Project Explorer view.
+ */
+public class ProjectExplorerViewRule extends ExternalResource {
+
+ private SWTBotView projectExplorerBotView;
+
+ public static final String PROJECT_EXPLORER_VIEW_ID = "org.eclipse.ui.navigator.ProjectExplorer";
+
+ @Override
+ protected void before() {
+ final SWTWorkbenchBot bot = new SWTWorkbenchBot();
+ SWTUtils.syncExec(() -> {
+ try {
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+ .showView(PROJECT_EXPLORER_VIEW_ID);
+ } catch (PartInitException e) {
+ e.printStackTrace();
+ return null;
+ }
+ });
+ this.projectExplorerBotView = bot.viewById(PROJECT_EXPLORER_VIEW_ID);
+ this.projectExplorerBotView.setFocus();
+ }
+
+ public SWTBotView getProjectExplorerBotView() {
+ return this.projectExplorerBotView;
+ }
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/RadioAssertion.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/RadioAssertion.java
new file mode 100644
index 0000000000..f27b18ed7f
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/RadioAssertion.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio;
+
+/**
+ * Custom assertions on a given {@link SWTBotRadio}.
+ */
+public class RadioAssertion extends AbstractSWTBotAssertions<RadioAssertion, SWTBotRadio> {
+
+ protected RadioAssertion(final SWTBotRadio actual) {
+ super(actual, RadioAssertion.class);
+ }
+
+ public static RadioAssertion assertThat(final SWTBotRadio actual) {
+ return new RadioAssertion(actual);
+ }
+
+ public RadioAssertion isSelected() {
+ notNullValue();
+ if(!actual.isSelected()) {
+ failWithMessage("Expected checkbox with text '%s' to be checked but it was not", actual.getText());
+ }
+ return this;
+ }
+
+ public RadioAssertion isNotSelected() {
+ notNullValue();
+ if(actual.isSelected()) {
+ failWithMessage("Expected checkbox with text '%s' to be unchecked but it was not", actual.getText());
+ }
+ return this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotTreeItemAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotTreeItemAssertions.java
new file mode 100644
index 0000000000..3bafb92676
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotTreeItemAssertions.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.assertj.core.api.Assertions;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ *
+ */
+public class SWTBotTreeItemAssertions extends AbstractSWTBotAssertions<SWTBotTreeItemAssertions, SWTBotTreeItem> {
+
+ protected SWTBotTreeItemAssertions(final SWTBotTreeItem actual) {
+ super(actual, SWTBotTreeItemAssertions.class);
+ }
+
+ public static SWTBotTreeItemAssertions assertThat(final SWTBotTreeItem containerPortsTreeItem) {
+ return new SWTBotTreeItemAssertions(containerPortsTreeItem);
+ }
+
+ public SWTBotTreeItemAssertions isExpanded() {
+ notNullValue();
+ if(!actual.isExpanded()) {
+ failWithMessage("Expected tree item %s to be expanded but it was not.", actual.getText());
+ }
+ return this;
+ }
+
+ /**
+ * Checks the number of items and also verifies that each item has an images and a text
+ * @param expectedCount
+ * @return
+ */
+ public SWTBotTreeItemAssertions hasChildItems(final int expectedCount) {
+ notNullValue();
+ if(actual.getItems().length != expectedCount) {
+ failWithMessage("Expected tree item %s to be have %s items but it had %s.", actual.getText(), expectedCount, actual.getItems().length);
+ }
+ for (SWTBotTreeItem swtBotTreeItem : actual.getItems()) {
+ final String treeItemText = SWTUtils.syncExec(() -> swtBotTreeItem.getText());
+ final Image treeItemWidgetImage = SWTUtils.syncExec(() -> swtBotTreeItem.widget.getImage());
+ Assertions.assertThat(treeItemText).isNotNull();
+ Assertions.assertThat(treeItemWidgetImage).isNotNull();
+ }
+ return this;
+ }
+
+ public SWTBotTreeItemAssertions hasText(final String expectedText) {
+ notNullValue();
+ if(!actual.getText().equals(expectedText)) {
+ failWithMessage("Expected node to have text %s but it was %s", expectedText, actual.getText());
+ }
+ return this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotViewRule.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotViewRule.java
new file mode 100644
index 0000000000..1edfaae938
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTBotViewRule.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.PlatformUI;
+import org.junit.Assert;
+import org.junit.rules.ExternalResource;
+
+/**
+ *
+ */
+public class SWTBotViewRule extends ExternalResource {
+
+ private final SWTWorkbenchBot bot = new SWTWorkbenchBot();
+
+ private final String viewId;
+
+ private SWTBotView botView = null;
+
+ private IViewPart view = null;
+
+ public SWTBotViewRule(final String viewId) {
+ this.viewId = viewId;
+ }
+
+ @Override
+ protected void before() {
+ SWTUtils.asyncExec(() -> {
+ try {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(this.viewId);
+ } catch (Exception e) {
+ e.printStackTrace();
+ Assert.fail("Failed to open view with id '" + this.viewId + "': " + e.getMessage());
+ }
+ });
+ this.botView = this.bot.viewById(this.viewId);
+ this.botView.show();
+ this.view = this.botView.getViewReference().getView(true);
+ }
+
+ public SWTBotView bot() {
+ return this.botView;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T view() {
+ return (T) view;
+ }
+
+ public void close() {
+ this.botView.close();
+ }
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTUtils.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTUtils.java
new file mode 100644
index 0000000000..86dfff27b3
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/SWTUtils.java
@@ -0,0 +1,508 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat Inc. and others.
+ * 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
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.assertj.core.api.Assertions.fail;
+
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Tree;
+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.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.progress.UIJob;
+import org.junit.Assert;
+import org.junit.ComparisonFailure;
+
+/**
+ * Utility class for SWT
+ */
+public class SWTUtils {
+
+ /**
+ * Calls <strong>synchronously</strong> the given {@link Supplier} in the
+ * default Display and returns the result
+ *
+ * @param supplier
+ * the Supplier to call
+ * @return the supplier's result
+ */
+ public static <V> V syncExec(final Supplier<V> supplier) {
+ final Queue<V> result = new ArrayBlockingQueue<>(1);
+ Display.getDefault().syncExec(() -> result.add(supplier.get()));
+ return result.poll();
+ }
+
+ /**
+ * Executes <strong>synchronously</strong> the given {@link Runnable} in the
+ * default Display
+ *
+ * @param runnable
+ * the {@link Runnable} to execute
+ */
+ public static void syncExec(final Runnable runnable) {
+ Display.getDefault().syncExec(runnable);
+ }
+
+ /**
+ * Executes <strong>synchronously</strong> the given {@link Runnable} in the
+ * default Display. The given {@link Runnable} is ran into a rapping
+ * {@link Runnable} that will catch the {@link ComparisonFailure} that may
+ * be raised during an assertion.
+ *
+ * @param runnable
+ * the {@link Runnable} to execute
+ * @throws ComparisonFailure
+ * if an assertion failed.
+ * @throws SWTException
+ * if an {@link SWTException} occurred
+ */
+ public static void syncAssert(final Runnable runnable) throws SWTException, ComparisonFailure {
+ final Queue<ComparisonFailure> failure = new ArrayBlockingQueue<>(1);
+ final Queue<SWTException> swtException = new ArrayBlockingQueue<>(1);
+ Display.getDefault().syncExec(() -> {
+ try {
+ runnable.run();
+ } catch (ComparisonFailure e1) {
+ failure.add(e1);
+ } catch (SWTException e2) {
+ swtException.add(e2);
+ }
+ });
+ if (!failure.isEmpty()) {
+ throw failure.poll();
+ }
+ if (!swtException.isEmpty()) {
+ throw swtException.poll();
+ }
+ }
+
+ /**
+ * Executes the given {@link Runnable} <strong>asynchronously</strong> in
+ * the default {@link Display} and waits until all jobs are done before
+ * completing.
+ *
+ * @param runnable
+ * @throws InterruptedException
+ */
+ public static void asyncExec(final Runnable runnable) {
+ asyncExec(runnable, true);
+ }
+
+ /**
+ * Executes the given {@link Runnable} <strong>asynchronously</strong> in
+ * the default {@link Display} and waits until all jobs are done before
+ * completing.
+ *
+ * @param runnable
+ * the {@link Runnable} to execute
+ * @param waitForJobsToComplete
+ * boolean flag to indicate if the method should wait for all
+ * jobs to complete before finishing
+ * @throws InterruptedException
+ */
+ public static void asyncExec(final Runnable runnable, final boolean waitForJobsToComplete) {
+ final Queue<ComparisonFailure> failure = new ArrayBlockingQueue<>(1);
+ final Queue<SWTException> swtException = new ArrayBlockingQueue<>(1);
+ Display.getDefault().asyncExec(() -> {
+ try {
+ runnable.run();
+ } catch (ComparisonFailure e1) {
+ failure.add(e1);
+ } catch (SWTException e2) {
+ swtException.add(e2);
+ }
+ });
+ if (waitForJobsToComplete) {
+ waitForJobsToComplete();
+ }
+ if (!failure.isEmpty()) {
+ throw failure.poll();
+ }
+ if (!swtException.isEmpty()) {
+ throw swtException.poll();
+ }
+ }
+
+ /**
+ * Waits for all {@link Job} to complete.
+ *
+ * @throws InterruptedException
+ */
+ public static void waitForJobsToComplete() {
+ wait(1, TimeUnit.SECONDS);
+ while (!Job.getJobManager().isIdle()) {
+ wait(1, TimeUnit.SECONDS);
+ }
+ }
+
+
+ /**
+ * @param viewBot
+ * the {@link SWTBotView} containing the {@link Tree} to traverse
+ * @param paths
+ * the node path in the {@link SWTBotTree} associated with the
+ * given {@link SWTBotView}
+ * @return the first {@link SWTBotTreeItem} matching the given node names
+ */
+ public static SWTBotTreeItem getTreeItem(final SWTBotView viewBot, final String... paths) {
+ final SWTBotTree tree = viewBot.bot().tree();
+ return getTreeItem(tree.getAllItems(), paths);
+ }
+
+ /**
+ *
+ * @param parentTreeItem
+ * the parent tree item from which to start
+ * @param paths
+ * the relative path to the item to return
+ * @return the {@link SWTBotTreeItem} that matches the given path from the
+ * given parent tree item
+ */
+ public static SWTBotTreeItem getTreeItem(final SWTBotTreeItem parentTreeItem, final String... paths) {
+ if (paths.length == 1) {
+ return getTreeItem(parentTreeItem, paths[0]);
+ }
+ final String[] remainingPaths = new String[paths.length - 1];
+ System.arraycopy(paths, 1, remainingPaths, 0, paths.length - 1);
+ return getTreeItem(getTreeItem(parentTreeItem, paths[0]), remainingPaths);
+ }
+
+ /**
+ * Returns the first child node in the given parent tree item whose text
+ * matches (ie, begins with) the given path argument.
+ *
+ * @param parentTree
+ * the parent tree item
+ * @param path
+ * the text of the node that should match
+ * @return the first matching node or <code>null</code> if none could be
+ * found
+ */
+ public static SWTBotTreeItem getTreeItem(final SWTBotTree parentTree, final String path) {
+ for (SWTBotTreeItem child : parentTree.getAllItems()) {
+ if (child.getText().startsWith(path)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the first child node in the given parent tree item whose text
+ * matches (ie, begins with) the given path argument.
+ *
+ * @param parentTreeItem
+ * the parent tree item
+ * @param path
+ * the text of the node that should match
+ * @return the first matching node or <code>null</code> if none could be
+ * found
+ */
+ public static SWTBotTreeItem getTreeItem(final SWTBotTreeItem parentTreeItem, final String path) {
+ for (SWTBotTreeItem child : parentTreeItem.getItems()) {
+ if (child.getText().startsWith(path)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ private static SWTBotTreeItem getTreeItem(final SWTBotTreeItem[] treeItems, final String[] paths) {
+ final SWTBotTreeItem swtBotTreeItem = Stream.of(treeItems).filter(item -> item.getText().startsWith(paths[0]))
+ .findFirst().orElseThrow(() -> new RuntimeException("Only available items: "
+ + Stream.of(treeItems).map(item -> item.getText()).collect(Collectors.joining(", "))));
+ if (paths.length > 1) {
+ syncExec(() -> swtBotTreeItem.expand());
+ final String[] remainingPath = new String[paths.length - 1];
+ System.arraycopy(paths, 1, remainingPath, 0, remainingPath.length);
+ return getTreeItem(swtBotTreeItem.getItems(), remainingPath);
+ }
+ return swtBotTreeItem;
+ }
+
+ public static SWTBotTableItem getListItem(final SWTBotTable table, final String name) {
+ return Stream.iterate(0, i -> i + 1).limit(table.rowCount()).map(rowNumber -> table.getTableItem(rowNumber))
+ .filter(rowItem -> {
+ return Stream.iterate(0, j -> j + 1).limit(table.columnCount())
+ .map(colNum -> rowItem.getText(colNum)).anyMatch(colValue -> colValue.contains(name));
+ }).findFirst().orElse(null);
+ }
+
+ /**
+ * Waits for the given duration
+ *
+ * @param duration
+ * the duration
+ * @param unit
+ * the duration unit
+ */
+ public static void wait(final int duration, final TimeUnit unit) {
+ try {
+ Thread.sleep(unit.toMillis(duration));
+ } catch (InterruptedException e) {
+ fail("Failed to wait for a " + unit.toMillis(duration) + "ms", e);
+ }
+ }
+
+ /**
+ * Selects <strong> all child items</strong> in the given
+ * <code>parentTreeItem</code> whose labels match the given
+ * <code>items</code>.
+ *
+ * @param parentTreeItem
+ * the parent tree item
+ * @param matchItems
+ * the items to select
+ * @return
+ */
+ public static SWTBotTreeItem select(final SWTBotTreeItem parentTreeItem, final String... matchItems) {
+ final List<String> fullyQualifiedItems = Stream.of(parentTreeItem.getItems()).filter(
+ treeItem -> Stream.of(matchItems).anyMatch(matchItem -> treeItem.getText().startsWith(matchItem)))
+ .map(item -> item.getText()).collect(Collectors.toList());
+ return parentTreeItem.select(fullyQualifiedItems.toArray(new String[0]));
+ }
+
+ /**
+ * Selects <strong> all child items</strong> in the given
+ * <code>parentTreeItem</code> whose labels match the given
+ * <code>items</code>.
+ *
+ * @param parentTree
+ * the parent tree
+ * @param matchItems
+ * the items to select
+ * @return
+ */
+ public static SWTBotTree select(final SWTBotTree parentTree, final String... matchItems) {
+ final List<String> fullyQualifiedItems = Stream.of(parentTree.getAllItems()).filter(
+ treeItem -> Stream.of(matchItems).anyMatch(matchItem -> treeItem.getText().startsWith(matchItem)))
+ .map(item -> item.getText()).collect(Collectors.toList());
+ return parentTree.select(fullyQualifiedItems.toArray(new String[0]));
+ }
+
+ /**
+ * Selects the given <code>treeItem</code> whose labels match the given
+ * <code>items</code>.
+ *
+ * @param treeItem
+ * the parent tree item
+ * @param matchItems
+ * the items to select
+ */
+ public static void select(SWTBotTreeItem treeItem) {
+ treeItem.select();
+ }
+
+ /**
+ * @param tree
+ * the root {@link SWTBotTree}
+ * @param path
+ * the path for the menu
+ * @return the child {@link SWTBotMenu} named with the first item in the
+ * given <code>path</code> from the given {@link SWTBotTree}
+ */
+ public static SWTBotMenu getContextMenu(final SWTBotTree tree, String... path) {
+ final SWTBotMenu contextMenu = tree.contextMenu(path[0]);
+ if (contextMenu == null) {
+ Assert.fail("Failed to find context menu '" + path[0] + "'.");
+ }
+ if (path.length == 1) {
+ return contextMenu;
+ }
+ final String[] remainingPath = new String[path.length - 1];
+ System.arraycopy(path, 1, remainingPath, 0, remainingPath.length);
+ return getSubMenu(contextMenu, remainingPath);
+ }
+
+ /**
+ * Hides the menu for the given <code>tree</code>
+ *
+ * @param tree
+ * the tree whose {@link Menu} should be hidden
+ */
+ public static void hideMenu(final SWTBotTree tree) {
+ try {
+ final Menu menu = UIThreadRunnable.syncExec((Result<Menu>) () -> tree.widget.getMenu());
+ UIThreadRunnable.syncExec(new VoidResult() {
+
+ @Override
+ public void run() {
+ hide(menu);
+ }
+
+ private void hide(final Menu menu) {
+ menu.notifyListeners(SWT.Hide, new Event());
+ if (menu.getParentMenu() != null) {
+ hide(menu.getParentMenu());
+ }
+ }
+ });
+ } catch (WidgetNotFoundException e) {
+ // ignore if widget is not found, that's probably because there's no
+ // tree in the
+ // Docker Explorer view for the test that just ran.
+ }
+ }
+
+ /**
+ * @param menu
+ * the parent menu
+ * @param path
+ * the path for the menu
+ * @return the child {@link SWTBotMenu} named with the first item in the
+ * given <code>path</code> from the given {@link SWTBotMenu}
+ */
+ public static SWTBotMenu getSubMenu(final SWTBotMenu menu, String... path) {
+ final SWTBotMenu subMenu = menu.menu(path[0]);
+ if (subMenu == null) {
+ Assert.fail("Failed to find submenu '" + path[0] + "'.");
+ }
+ if (path.length == 1) {
+ return subMenu;
+ }
+ final String[] remainingPath = new String[path.length - 1];
+ System.arraycopy(path, 1, remainingPath, 0, remainingPath.length);
+ return getSubMenu(subMenu, remainingPath);
+ }
+
+ public static SWTBotTreeItem expand(final SWTBotTree tree, final String... paths) {
+ final SWTBotTreeItem rootItem = getTreeItem(tree, paths[0]);
+ expandTreeItem(rootItem);
+ if (paths.length > 1) {
+ final String[] remainingPath = new String[paths.length - 1];
+ System.arraycopy(paths, 1, remainingPath, 0, remainingPath.length);
+ return expand(rootItem, remainingPath);
+ }
+ return rootItem;
+ }
+
+ public static SWTBotTreeItem expand(final SWTBotTreeItem treeItem, final String... paths) {
+ final SWTBotTreeItem childItem = getTreeItem(treeItem, paths[0]);
+ expandTreeItem(childItem);
+ if (paths.length > 1) {
+ final String[] remainingPath = new String[paths.length - 1];
+ System.arraycopy(paths, 1, remainingPath, 0, remainingPath.length);
+ return expand(childItem, remainingPath);
+ }
+ return getTreeItem(treeItem, paths[0]);
+ }
+
+ private static SWTBotTreeItem expandTreeItem(final SWTBotTreeItem treeItem) {
+ final UIJob expandJob = new UIJob("expanding tree") {
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ treeItem.expand();
+ return Status.OK_STATUS;
+ }
+ };
+ expandJob.addJobChangeListener(new JobChangeAdapter() {
+ @Override
+ public void done(IJobChangeEvent event) {
+ final int maxAttempts = 30;
+ int currentAttempt = 0;
+ while (currentAttempt < maxAttempts && treeItem.getItems().length == 1
+ && treeItem.getItems()[0].getText().isEmpty()) {
+ SWTUtils.wait(1, TimeUnit.SECONDS);
+ currentAttempt++;
+ }
+
+ }
+ });
+ expandJob.schedule();
+ SWTUtils.wait(1, TimeUnit.SECONDS);
+ return treeItem;
+ }
+
+ public static SWTBotView getSWTBotView(final SWTWorkbenchBot bot, final String viewId) {
+ return bot.views().stream().filter(v -> v.getViewReference().getId().equals(viewId)).findFirst().orElse(null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T getView(final SWTWorkbenchBot bot, final String viewId) {
+ return (T) getView(bot, viewId, false);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T getView(final SWTWorkbenchBot bot, final String viewId, final boolean restore) {
+ final SWTBotView viewBot = bot.viewById(viewId);
+ viewBot.setFocus();
+ return (T) viewBot.getReference().getView(restore);
+ }
+
+ /**
+ * @return <code>true</code> if the Console view is visible in the active
+ * page, <code>false</code> otherwise.
+ * @throws InterruptedException
+ */
+ public static boolean isConsoleViewVisible(final SWTWorkbenchBot bot) {
+ return bot.views().stream()
+ .anyMatch(v -> v.getViewReference().getId().equals(IConsoleConstants.ID_CONSOLE_VIEW));
+ }
+
+ public static SWTBotToolbarButton getConsoleToolbarButtonWithTooltipText(final SWTWorkbenchBot bot, final String tooltipText) {
+ return bot.viewById(IConsoleConstants.ID_CONSOLE_VIEW).getToolbarButtons().stream()
+ .filter(button -> button.getToolTipText().equals(tooltipText)).findFirst().get();
+ }
+
+ public static void closeView(final SWTWorkbenchBot bot, final String viewId) {
+ bot.views().stream().filter(v -> v.getReference().getId().equals(viewId)).forEach(v -> v.close());
+ }
+
+ /**
+ * Creates a new {@link SWTBotMenu} from the context. This avoids some
+ * unexpected "Widget is disposed" errors.
+ *
+ * @param bot
+ * the bot
+ * @param menuName
+ * the name of the menu to find
+ * @return the context menu
+ * @see <a href=
+ * "https://www.eclipse.org/forums/index.php?t=msg&th=11863&start=0&">Eclipse
+ * forum</a>
+ */
+ public static SWTBotMenu getContextMenu(final AbstractSWTBot<? extends Control> bot, final String menuName) {
+ return new SWTBotMenu(ContextMenuHelper.contextMenu(bot, menuName));
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TabDescriptorAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TabDescriptorAssertions.java
new file mode 100644
index 0000000000..ad63cd14bf
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TabDescriptorAssertions.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.assertj.core.api.AbstractAssert;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+
+/**
+ * Custom assertions on a given {@link ITabDescriptor}.
+ */
+public class TabDescriptorAssertions extends AbstractAssert<TabDescriptorAssertions, ITabDescriptor> {
+
+ protected TabDescriptorAssertions(final ITabDescriptor actual) {
+ super(actual, TabDescriptorAssertions.class);
+ }
+
+ public static TabDescriptorAssertions assertThat(final ITabDescriptor actual) {
+ return new TabDescriptorAssertions(actual);
+ }
+
+ public TabDescriptorAssertions hasId(final String id) {
+ notNullValue();
+ if (!actual.getId().equals(id)) {
+ failWithMessage("Expected tab section with id '%s' to be selected but it was '%s'", id, actual.getId());
+ }
+ return this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TestLoggerRule.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TestLoggerRule.java
new file mode 100644
index 0000000000..e74744252a
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TestLoggerRule.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+/**
+ *
+ */
+public class TestLoggerRule extends TestWatcher {
+
+ @Override
+ protected void starting(final Description description) {
+ System.out.println("Starting " + description.getClassName() + "." + description.getMethodName());
+ }
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TextAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TextAssertions.java
new file mode 100644
index 0000000000..1b33a1da8c
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/TextAssertions.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
+
+/**
+ * Custom assertions on an {@link SWTBotText}.
+ */
+public class TextAssertions extends AbstractSWTBotAssertions<TextAssertions, SWTBotText> {
+
+ protected TextAssertions(final SWTBotText actual) {
+ super(actual, TextAssertions.class);
+ }
+
+ public static TextAssertions assertThat(final SWTBotText actual) {
+ return new TextAssertions(actual);
+ }
+
+ public TextAssertions isEmpty() {
+ notNullValue();
+ if(!actual.getText().isEmpty()) {
+ failWithMessage("Expected text widget to be empty but it contained '%s'", actual.getText());
+ }
+ return this;
+ }
+
+ public TextAssertions textEquals(final String expectedContent) {
+ notNullValue();
+ if(!actual.getText().equals(expectedContent)) {
+ failWithMessage("Expected text widget to contain '%s' but it contained '%s'", expectedContent, actual.getText());
+ }
+ return this;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ToolbarButtonAssertions.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ToolbarButtonAssertions.java
new file mode 100644
index 0000000000..07df9e0885
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/ToolbarButtonAssertions.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.meson.ui.tests.utils;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
+
+/**
+ * Custom assertions on a given {@link SWTBotButton}.
+ */
+public class ToolbarButtonAssertions extends AbstractSWTBotAssertions<ToolbarButtonAssertions, SWTBotToolbarButton> {
+
+ protected ToolbarButtonAssertions(final SWTBotToolbarButton actual) {
+ super(actual, ToolbarButtonAssertions.class);
+ }
+
+ public static ToolbarButtonAssertions assertThat(final SWTBotToolbarButton actual) {
+ return new ToolbarButtonAssertions(actual);
+ }
+
+}
diff --git a/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/package-info.java b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/package-info.java
new file mode 100644
index 0000000000..3cd97f3909
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/src/org/eclipse/cdt/internal/meson/ui/tests/utils/package-info.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * 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
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+/**
+ * Classes to perform assertions on SWTBot controls.
+ */
+package org.eclipse.cdt.internal.meson.ui.tests.utils; \ No newline at end of file
diff --git a/build/org.eclipse.cdt.meson.ui.tests/swtbot-test-plugin.properties b/build/org.eclipse.cdt.meson.ui.tests/swtbot-test-plugin.properties
new file mode 100644
index 0000000000..338038b934
--- /dev/null
+++ b/build/org.eclipse.cdt.meson.ui.tests/swtbot-test-plugin.properties
@@ -0,0 +1 @@
+# This file tells the Maven build to use the settings for SWTBot test plugins

Back to the top