--- /dev/null
+package com.vaadin.tests.components.window;
+
+import java.util.concurrent.CompletableFuture;
+
+import com.vaadin.annotations.PreserveOnRefresh;
+import com.vaadin.annotations.Push;
+import com.vaadin.annotations.Theme;
+import com.vaadin.navigator.PushStateNavigation;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.communication.PushMode;
+import com.vaadin.shared.ui.ui.Transport;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.UIDetachedException;
+import com.vaadin.ui.Window;
+
+@Theme("tests-valo-disabled-animations")
+@PreserveOnRefresh
+@Push(value = PushMode.MANUAL, transport = Transport.LONG_POLLING)
+@PushStateNavigation
+public class CloseWindowAsync extends AbstractTestUIWithLog {
+ private final boolean manualPush;
+
+ public CloseWindowAsync() {
+ this(true);
+ }
+
+ public CloseWindowAsync(boolean manualPush) {
+ this.manualPush = manualPush;
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Button button = new Button("Open and directly close busy window");
+ button.addClickListener((Button.ClickListener) event -> {
+ final Window window = createWindow(1);
+ final UI ui = getUI();
+ ui.addWindow(window);
+
+ CompletableFuture.runAsync(() -> {
+ // task duration variable, could be a few ms or longer
+ ui.accessSynchronously(() -> {
+ window.close();
+ if (manualPush) {
+ ui.push();
+ }
+ });
+ });
+ });
+ addComponents(button);
+
+ final Button button2 = new Button(
+ "Open and directly close busy window with error notification");
+ button2.addClickListener((Button.ClickListener) event -> {
+ final Window window = createWindow(2);
+ final UI ui = getUI();
+ ui.addWindow(window);
+
+ CompletableFuture.runAsync(() -> {
+ // task duration variable, could be a few ms or longer
+ ui.accessSynchronously(() -> {
+ window.close();
+ Notification.show("error", Notification.Type.ERROR_MESSAGE);
+ if (manualPush) {
+ ui.push();
+ }
+ });
+ });
+ });
+ addComponents(button2);
+
+ // Reconstructed the issue using the vaadin push training
+ // https://vaadin.com/learn/training/vaadin-push
+
+ final Button button3 = new Button(
+ "Open and directly close busy window (vaadin push training)");
+ button3.addClickListener((Button.ClickListener) event -> {
+ final Window window = createWindow(3);
+ final UI ui = getUI();
+ ui.addWindow(window);
+
+ CompletableFuture.runAsync(() -> {
+ // task duration variable, could be a few ms or longer
+ try {
+ ui.access(() -> {
+ ui.removeWindow(window);
+ if (manualPush) {
+ ui.push();
+ }
+ });
+ } catch (UIDetachedException e) {
+ // browser closed
+ }
+ });
+ });
+ addComponents(button3);
+ }
+
+ private Window createWindow(int index) {
+ final Window window = new Window();
+ window.setCaption("Window");
+ window.setWidth(30, Unit.PERCENTAGE);
+ window.setHeight(30, Unit.PERCENTAGE);
+ window.setModal(true);
+ window.setContent(new Label("Window content"));
+ window.addCloseListener(e -> log("closed " + index));
+ return window;
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11942;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "All buttons should successfully open and close window on all browsers.";
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.vaadin.tests.components.window;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class CloseWindowAsyncTest extends MultiBrowserTest {
+
+ @Test
+ public void testOpeningAndClosing() throws Exception {
+ openTestURL();
+ List<ButtonElement> buttons = $(ButtonElement.class).all();
+ int index = 1;
+ for (ButtonElement button : buttons) {
+ button.click();
+ List<NotificationElement> notifications = $(
+ NotificationElement.class).all();
+ if (!notifications.isEmpty()) {
+ notifications.get(0).close();
+ }
+ assertEquals("Unexpected log contents,",
+ index + ". closed " + index, getLogRow(0));
+ ++index;
+ }
+ }
+}