diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java
index 48fb51bea9d..96f328f3f36 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java	
+++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java	
@@ -261,7 +261,7 @@ static int callAndWait(long[] ppv, ToIntFunction<IUnknown> callable) {
 	// "completion" callback may be called asynchronously,
 	// so keep processing next OS message that may call it
 	while (phr[0] == COM.S_OK && ppv[0] == 0) {
-		processNextOSMessage();
+		spinEventLoop();
 	}
 	completion.Release();
 	return phr[0];
@@ -281,7 +281,7 @@ static int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
 	// "completion" callback may be called asynchronously,
 	// so keep processing next OS message that may call it
 	while (phr[0] == COM.S_OK && pstr[0] == null) {
-		processNextOSMessage();
+		spinEventLoop();
 	}
 	completion.Release();
 	return phr[0];
@@ -444,31 +444,17 @@ void scheduleWebViewTask(Runnable action) {
 
 	private <T> void waitForFutureToFinish(CompletableFuture<T> future) {
 		while(!future.isDone()) {
-			processNextOSMessage();
+			spinEventLoop();
 		}
 	}
 
 }
 
-/**
- * Processes a single OS message using {@link Display#readAndDispatch()}. This
- * is required for processing the OS events during browser initialization, since
- * Edge browser initialization happens asynchronously.
- * <p>
- * {@link Display#readAndDispatch()} also processes events scheduled for
- * asynchronous execution via {@link Display#asyncExec(Runnable)}. This may
- * include events such as the disposal of the browser's parent composite, which
- * leads to a failure in browser initialization if processed in between the OS
- * events for initialization. Thus, this method does not implement an ordinary
- * readAndDispatch loop, but waits for an OS event to be processed.
- */
-private static void processNextOSMessage() {
+private static void spinEventLoop() {
 	Display display = Display.getCurrent();
-	MSG msg = new MSG();
-	while (!OS.PeekMessage (msg, 0, 0, 0, OS.PM_NOREMOVE)) {
+	if (!display.readAndDispatch()) {
 		display.sleep();
 	}
-	display.readAndDispatch();
 }
 
 static ICoreWebView2CookieManager getCookieManager() {
@@ -588,20 +574,23 @@ private void createInstance(int previousAttempts) {
 
 private IUnknown createControllerInitializationCallback(int previousAttempts) {
 	Runnable initializationRollback = () -> {
-		webViewProvider.abortInitialization();
 		if (environment2 != null) {
 			environment2.Release();
 			environment2 = null;
 		}
 		containingEnvironment.instances().remove(this);
 	};
+	Runnable initializationAbortion = () -> {
+		webViewProvider.abortInitialization();
+		initializationRollback.run();
+	};
 	return newCallback((result, pv) -> {
 		if (browser.isDisposed()) {
-			initializationRollback.run();
+			initializationAbortion.run();
 			return COM.S_OK;
 		}
 		if (result == OS.HRESULT_FROM_WIN32(OS.ERROR_INVALID_STATE)) {
-			initializationRollback.run();
+			initializationAbortion.run();
 			SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
 					" Edge instance with same data folder but different environment options already exists");
 		}
@@ -611,11 +600,11 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
 			setupBrowser((int) result, pv);
 			break;
 		case COM.E_WRONG_THREAD:
-			initializationRollback.run();
+			initializationAbortion.run();
 			error(SWT.ERROR_THREAD_INVALID_ACCESS, (int) result);
 			break;
 		case COM.E_ABORT:
-			initializationRollback.run();
+			initializationAbortion.run();
 			break;
 		default:
 			initializationRollback.run();
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java
index f76da4c2d77..d657d67bab2 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java	
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java	
@@ -81,7 +81,6 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Ignore;
 import org.junit.Rule;
@@ -158,16 +157,6 @@ public Test_org_eclipse_swt_browser_Browser(int swtBrowserSettings) {
 	this.swtBrowserSettings = swtBrowserSettings;
 }
 
-@BeforeClass
-public static void setupEdgeEnvironment() {
-	// initialize Edge environment before any test runs to isolate environment setup
-	if (SwtTestUtil.isWindows) {
-		Shell shell = new Shell();
-		new Browser(shell, SWT.EDGE);
-		shell.dispose();
-	}
-}
-
 @Override
 @Before
 public void setUp() {
@@ -302,11 +291,17 @@ private int reportOpenedDescriptors() {
 }
 
 private Browser createBrowser(Shell s, int flags) {
+	return createBrowser(s, flags, true);
+}
+
+private Browser createBrowser(Shell s, int flags, boolean expectSuccess) {
 	long maximumBrowserCreationMilliseconds = 90_000;
 	long createStartTime = System.currentTimeMillis();
 	Browser b = new Browser(s, flags);
 	// Wait for asynchronous initialization via getting URL
-	b.getUrl();
+	if (expectSuccess) {
+		b.getUrl();
+	}
 	createdBroswers.add(b);
 	long createDuration = System.currentTimeMillis() - createStartTime;
 	assertTrue("creating browser took too long: " + createDuration + "ms", createDuration < maximumBrowserCreationMilliseconds);
@@ -334,7 +329,7 @@ public void test_Constructor_asyncParentDisposal() {
 	Display.getCurrent().asyncExec(() -> {
 		shell.dispose();
 	});
-	Browser browser = createBrowser(shell, swtBrowserSettings);
+	Browser browser = createBrowser(shell, swtBrowserSettings, false);
 	assertFalse(browser.isDisposed());
 }
 
@@ -434,6 +429,27 @@ public void test_evalute_Cookies () {
 	assertFalse(res.isEmpty());
 }
 
+@Test
+public void test_evaluate_callingIntoSwt() throws Exception {
+	AtomicBoolean initialLoad = new AtomicBoolean();
+	AtomicBoolean openWindowListenerCalled = new AtomicBoolean();
+	browser.addProgressListener(ProgressListener.completedAdapter(e -> initialLoad.set(true)));
+	browser.addOpenWindowListener(event -> {
+		event.required = true; // block default
+		openWindowListenerCalled.set(true);
+	});
+	browser.setText("""
+			<button id="button" onClick="window.open('https://eclipse.org');">open eclipse.org</button>
+			""");
+	waitForPassCondition(initialLoad::get);
+
+	browser.evaluate("""
+				document.getElementById("button").click();
+			""");
+
+	waitForPassCondition(openWindowListenerCalled::get);
+}
+
 @Test
 public void test_ClearAllSessionCookies () {
 	// clearSessions will only work for Webkit2 when >= 2.16