diff --git a/org.eclipse.e4.tools.emf.ui.tests/.classpath b/org.eclipse.e4.tools.emf.ui.tests/.classpath
new file mode 100644
index 0000000000..1aa9eca95a
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.e4.tools.emf.ui.tests/.project b/org.eclipse.e4.tools.emf.ui.tests/.project
new file mode 100644
index 0000000000..6de6bdf5ac
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/.project
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.e4.tools.emf.ui.tests
+
+
+
+
+
+ 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/org.eclipse.e4.tools.emf.ui.tests/.settings/org.eclipse.core.resources.prefs b/org.eclipse.e4.tools.emf.ui.tests/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/org.eclipse.e4.tools.emf.ui.tests/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.e4.tools.emf.ui.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..23fa13b170
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
+org.eclipse.jdt.core.compiler.compliance=21
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=21
diff --git a/org.eclipse.e4.tools.emf.ui.tests/META-INF/MANIFEST.MF b/org.eclipse.e4.tools.emf.ui.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..bd993c91ad
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: EMF UI Test-Fragment
+Bundle-SymbolicName: org.eclipse.e4.tools.emf.ui.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: Eclipse.org
+Fragment-Host: org.eclipse.e4.tools.emf.ui
+Automatic-Module-Name: org.eclipse.e4.tools.emf.ui.tests
+Bundle-RequiredExecutionEnvironment: JavaSE-21
+Import-Package: org.junit.jupiter.api;version="[5.14.3,6.0.0)"
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.ui.ide,
+ org.eclipse.e4.tools.emf.editor3x
diff --git a/org.eclipse.e4.tools.emf.ui.tests/build.properties b/org.eclipse.e4.tools.emf.ui.tests/build.properties
new file mode 100644
index 0000000000..b2b1eadba4
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/build.properties
@@ -0,0 +1,2 @@
+output.. = bin/
+bin.includes = META-INF/
diff --git a/org.eclipse.e4.tools.emf.ui.tests/src/org/eclipse/e4/tools/emf/ui/internal/common/component/tabs/tests/XmiTabTest.java b/org.eclipse.e4.tools.emf.ui.tests/src/org/eclipse/e4/tools/emf/ui/internal/common/component/tabs/tests/XmiTabTest.java
new file mode 100644
index 0000000000..7220fa3bb0
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/src/org/eclipse/e4/tools/emf/ui/internal/common/component/tabs/tests/XmiTabTest.java
@@ -0,0 +1,131 @@
+package org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.tests;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.XmiTab;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.osgi.framework.FrameworkUtil;
+
+public class XmiTabTest {
+
+ private static final String MODEL_EDITOR_ID = "org.eclipse.e4.tools.emf.editor3x.e4wbm"; //$NON-NLS-1$
+
+ private IProject project;
+ private XmiTab xmiTab;
+ private Text searchTextWidget;
+ private StyledText sourceViewerTextWidget;
+
+ @BeforeEach
+ void setup() throws IOException, CoreException {
+ project = importTestProject("/tests/projects/xmitabtest");
+ waitForUI();
+
+ IFile file = project.getFile("src/Application.e4xmi");
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IEditorPart part = IDE.openEditor(page, file, MODEL_EDITOR_ID, true);
+ IEclipseContext context = part.getSite().getService(IEclipseContext.class);
+ Composite composite = context.get(Composite.class);
+ waitForUI();
+
+ CTabFolder folder = (CTabFolder) composite.getChildren()[0];
+ folder.setSelection(2 /* XMI tab index */);
+ waitForUI();
+
+ xmiTab = (XmiTab) folder.getSelection().getControl();
+ searchTextWidget = (Text) xmiTab.getChildren()[0];
+ Composite sourceViewerComposite = (Composite) xmiTab.getChildren()[1];
+ sourceViewerTextWidget = (StyledText) sourceViewerComposite.getChildren()[0];
+ }
+
+ @AfterEach
+ void tearDown() throws CoreException {
+ if (project != null) {
+ project.delete(IProject.FORCE | IProject.NEVER_DELETE_PROJECT_CONTENT, null);
+ }
+ }
+
+ @Test
+ void testSearchHighlight() {
+ searchTextWidget.forceFocus();
+ waitForUI();
+
+ Display display = Display.getDefault();
+ display.post(keyEvent('a', SWT.KeyDown, display.getFocusControl()));
+ waitForUI();
+
+ int[] ranges = sourceViewerTextWidget.getSelectionRanges();
+ assertEquals(ranges[0], 41);
+ assertEquals(ranges[1], 1);
+
+ display.post(keyEvent('d', SWT.KeyDown, display.getFocusControl()));
+ waitForUI();
+
+ ranges = sourceViewerTextWidget.getSelectionRanges();
+ assertEquals(ranges[0], 262);
+ assertEquals(ranges[1], 2);
+
+ // find next occurrence
+ display.post(keyEvent(SWT.CR, SWT.KeyDown, display.getFocusControl()));
+ waitForUI();
+
+ ranges = sourceViewerTextWidget.getSelectionRanges();
+ assertEquals(ranges[0], 467);
+ assertEquals(ranges[1], 2);
+ }
+
+ private static void waitForUI() {
+ while (Display.getDefault().readAndDispatch()) {
+ // wait for UI
+ }
+ }
+
+ private static Event keyEvent(int key, int type, Widget widget) {
+ Event e = new Event();
+ e.keyCode = key;
+ e.character = (char) key;
+ e.type = type;
+ e.widget = widget;
+ return e;
+ }
+
+ private static IProject importTestProject(String path) throws IOException, CoreException {
+ URL entry = FileLocator
+ .toFileURL(FileLocator.find(FrameworkUtil.getBundle(XmiTabTest.class), IPath.fromOSString(path)));
+ if (entry == null) {
+ throw new IllegalArgumentException(path + " does not exist");
+ }
+ IPath projectFile = IPath.fromPortableString(entry.getPath()).append(IProjectDescription.DESCRIPTION_FILE_NAME);
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IProjectDescription projectDescription = workspace.loadProjectDescription(projectFile);
+ IProject project = workspace.getRoot().getProject(projectDescription.getName());
+ project.create(projectDescription, null);
+ project.open(null);
+ return project;
+ }
+}
diff --git a/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.classpath b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.classpath
new file mode 100644
index 0000000000..463d5f95dc
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.project b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.project
new file mode 100644
index 0000000000..b746fd781d
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.project
@@ -0,0 +1,17 @@
+
+
+ xmitabtest
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.settings/org.eclipse.core.resources.prefs b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..9a7984bb6c
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=21
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=21
diff --git a/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/src/Application.e4xmi b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/src/Application.e4xmi
new file mode 100644
index 0000000000..930dff2fe8
--- /dev/null
+++ b/org.eclipse.e4.tools.emf.ui.tests/tests/projects/xmitabtest/src/Application.e4xmi
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+