diff options
Diffstat (limited to 'uitest/src')
3 files changed, 143 insertions, 0 deletions
diff --git a/uitest/src/com/vaadin/tests/application/ResynchronizeAfterAsyncRemoval.java b/uitest/src/com/vaadin/tests/application/ResynchronizeAfterAsyncRemoval.java new file mode 100644 index 0000000000..d8f7fface3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/ResynchronizeAfterAsyncRemoval.java @@ -0,0 +1,77 @@ +package com.vaadin.tests.application; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Set; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.ConnectorTracker; +import com.vaadin.ui.Window; + +public class ResynchronizeAfterAsyncRemoval extends AbstractTestUIWithLog { + + @Override + public void setup(VaadinRequest vaadinRequest) { + final Window window = new Window("Asynchronously removed window"); + window.center(); + + // The window will enqueue a non-immediate message reporting its current + // position. + addWindow(window); + + // Remove window immediately when the current response is sent + runAfterResponse(new Runnable() { + @Override + public void run() { + removeWindow(window); + } + }); + + // Clicking the button will trigger sending the window coordinates, but + // the window is already removed at that point. + addComponent(new Button("Am I dirty?", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + log("Window removed: " + (window.getParent() == null)); + + boolean dirty = getUI().getConnectorTracker().isDirty( + event.getButton()); + log("Dirty: " + dirty); + } + })); + addComponent(new Button("Log unregistered connector count", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + logUnregisteredConnectorCount(); + } + })); + } + + private void logUnregisteredConnectorCount() { + int count = 0; + + Map<Integer, Set<String>> unregisterIdMap = getUnregisterIdMap(); + for (Set<String> set : unregisterIdMap.values()) { + count += set.size(); + } + log("syncId: " + getConnectorTracker().getCurrentSyncId()); + log("Unregistered connector count: " + count); + } + + @SuppressWarnings("unchecked") + private Map<Integer, Set<String>> getUnregisterIdMap() { + try { + ConnectorTracker tracker = getConnectorTracker(); + Field field = tracker.getClass().getDeclaredField( + "syncIdToUnregisteredConnectorIds"); + field.setAccessible(true); + return (Map<Integer, Set<String>>) field.get(tracker); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/application/ResynchronizeAfterAsyncRemovalTest.java b/uitest/src/com/vaadin/tests/application/ResynchronizeAfterAsyncRemovalTest.java new file mode 100644 index 0000000000..7f2dabe9f1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/ResynchronizeAfterAsyncRemovalTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.application; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class ResynchronizeAfterAsyncRemovalTest extends SingleBrowserTest { + @Test + public void noResyncAfterAsyncRemoval() { + openTestURL(); + + $(ButtonElement.class).first().click(); + + Assert.assertEquals("Timing issue in the test?", + "1. Window removed: true", getLogRow(1)); + + Assert.assertEquals( + "Removing window should not cause button to be marked as dirty", + "2. Dirty: false", getLogRow(0)); + + ButtonElement logCountButton = $(ButtonElement.class).all().get(1); + logCountButton.click(); + + Assert.assertEquals("Sanity check", "3. syncId: 2", getLogRow(1)); + Assert.assertEquals("Sanity check", + "4. Unregistered connector count: 1", getLogRow(0)); + + logCountButton.click(); + + Assert.assertEquals("Sanity check", "5. syncId: 3", getLogRow(1)); + Assert.assertEquals( + "Unregistered connector map should have been cleared", + "6. Unregistered connector count: 0", getLogRow(0)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/AbstractTestUI.java b/uitest/src/com/vaadin/tests/components/AbstractTestUI.java index dba055a65a..98b0f63ce1 100644 --- a/uitest/src/com/vaadin/tests/components/AbstractTestUI.java +++ b/uitest/src/com/vaadin/tests/components/AbstractTestUI.java @@ -205,4 +205,18 @@ public abstract class AbstractTestUI extends UI { return getSession().getBrowser(); } + /** + * Execute the provided runnable on the UI thread as soon as the current + * request has been sent. + */ + protected void runAfterResponse(final Runnable runnable) { + // Immediately start a thread that will start waiting for the session to + // get unlocked. + new Thread() { + @Override + public void run() { + accessSynchronously(runnable); + } + }.start(); + } } |