* #11614: Added test which demonstrates that the fix is incomplete * #11614: UI.doRefresh() only calls navigator when the navigation state actually changes * Added javadoc to Navigator.getCurrentNavigationState() * Minor: Removed accidental star importstags/8.9.0.alpha1
ui.setNavigator(null); | ui.setNavigator(null); | ||||
} | } | ||||
/** | |||||
* Returns the current navigation state for which the | |||||
* {@link #getCurrentView()} has been constructed. This may differ to | |||||
* {@link #getState()} in case the URL has been changed on the browser and | |||||
* the navigator wasn't yet given an opportunity to construct new view. The | |||||
* state is in the form of | |||||
* <code>current-view-name/optional/parameters</code> | |||||
* | |||||
* @return the current navigation state, may be {@code null}. | |||||
*/ | |||||
public String getCurrentNavigationState() { | |||||
return currentNavigationState; | |||||
} | |||||
} | } |
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Map.Entry; | import java.util.Map.Entry; | ||||
import java.util.Objects; | |||||
import java.util.concurrent.Future; | import java.util.concurrent.Future; | ||||
import java.util.logging.Level; | import java.util.logging.Level; | ||||
import java.util.logging.Logger; | import java.util.logging.Logger; | ||||
private LoadingIndicatorConfiguration loadingIndicatorConfiguration = new LoadingIndicatorConfigurationImpl( | private LoadingIndicatorConfiguration loadingIndicatorConfiguration = new LoadingIndicatorConfigurationImpl( | ||||
this); | this); | ||||
/** | |||||
* Holder for old navigation state, needed in doRefresh in order not to call | |||||
* navigateTo too often | |||||
*/ | |||||
private String oldNavigationState; | |||||
/** | /** | ||||
* Scroll Y position. | * Scroll Y position. | ||||
*/ | */ | ||||
// PushStateNavigation. Call navigateTo only if state have | // PushStateNavigation. Call navigateTo only if state have | ||||
// truly changed | // truly changed | ||||
Navigator navigator = getNavigator(); | Navigator navigator = getNavigator(); | ||||
if (navigator != null) { | |||||
if (oldNavigationState == null) oldNavigationState = getNavigator().getState(); | |||||
if (!navigator.getState().equals(oldNavigationState)) { | |||||
navigator.navigateTo(navigator.getState()); | |||||
oldNavigationState = navigator.getState(); | |||||
} | |||||
if (navigator != null | |||||
&& !Objects.equals(navigator.getCurrentNavigationState(), | |||||
navigator.getState())) { | |||||
navigator.navigateTo(navigator.getState()); | |||||
} | } | ||||
} | } | ||||
import com.vaadin.navigator.View; | import com.vaadin.navigator.View; | ||||
import com.vaadin.server.VaadinRequest; | import com.vaadin.server.VaadinRequest; | ||||
import com.vaadin.tests.components.AbstractTestUI; | import com.vaadin.tests.components.AbstractTestUI; | ||||
import com.vaadin.ui.Button; | |||||
import com.vaadin.ui.Label; | import com.vaadin.ui.Label; | ||||
import com.vaadin.ui.UI; | |||||
import com.vaadin.ui.VerticalLayout; | import com.vaadin.ui.VerticalLayout; | ||||
@PreserveOnRefresh | @PreserveOnRefresh | ||||
protected void setup(VaadinRequest request) { | protected void setup(VaadinRequest request) { | ||||
final Navigator navigator = new Navigator(this, this); | final Navigator navigator = new Navigator(this, this); | ||||
navigator.addView("", MyView.class); | navigator.addView("", MyView.class); | ||||
navigator.addView("otherview", OtherView.class); | |||||
setNavigator(navigator); | setNavigator(navigator); | ||||
MyView.instanceNumber = 0; | |||||
OtherView.instanceNumber = 0; | |||||
} | } | ||||
public static class MyView extends VerticalLayout implements View { | public static class MyView extends VerticalLayout implements View { | ||||
public MyView() { | public MyView() { | ||||
instanceNumber++; | instanceNumber++; | ||||
addComponent(new Label("This is instance no " + instanceNumber)); | addComponent(new Label("This is instance no " + instanceNumber)); | ||||
addComponent(new Button("Navigate to otherview", e -> UI | |||||
.getCurrent().getNavigator().navigateTo("otherview"))); | |||||
} | |||||
} | |||||
public static class OtherView extends VerticalLayout implements View { | |||||
private static int instanceNumber = 0; | |||||
public OtherView() { | |||||
instanceNumber++; | |||||
addComponent(new Label( | |||||
"This is otherview instance no " + instanceNumber)); | |||||
} | } | ||||
} | } | ||||
} | } |
package com.vaadin.tests.components.ui; | package com.vaadin.tests.components.ui; | ||||
import com.vaadin.testbench.elements.ButtonElement; | |||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.testbench.elements.LabelElement; | import com.vaadin.testbench.elements.LabelElement; | ||||
$(LabelElement.class).first().getText()); | $(LabelElement.class).first().getText()); | ||||
// Reload the page; UI.refresh should be invoked | // Reload the page; UI.refresh should be invoked | ||||
openTestURL(); | |||||
reloadPage(); | |||||
assertEquals("The Label content is not matching", | assertEquals("The Label content is not matching", | ||||
"This is instance no 1", | "This is instance no 1", | ||||
$(LabelElement.class).first().getText()); | $(LabelElement.class).first().getText()); | ||||
} | } | ||||
@Test | |||||
public void testViewNotRecreatedAfterNavigation() { | |||||
openTestURL(); | |||||
assertEquals("This is instance no 1", | |||||
$(LabelElement.class).first().getText()); | |||||
// Reload the page; UI.refresh should be invoked | |||||
reloadPage(); | |||||
assertEquals("This is instance no 1", | |||||
$(LabelElement.class).first().getText()); | |||||
// now open the other view using the navigator | |||||
$(ButtonElement.class).first().click(); | |||||
assertEquals("This is otherview instance no 1", | |||||
$(LabelElement.class).first().getText()); | |||||
// Reload the page; UI.refresh should be invoked | |||||
reloadPage(); | |||||
assertEquals("This is otherview instance no 1", | |||||
$(LabelElement.class).first().getText()); | |||||
} | |||||
} | } |
import org.junit.runner.Description; | import org.junit.runner.Description; | ||||
import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||
import org.openqa.selenium.By; | import org.openqa.selenium.By; | ||||
import org.openqa.selenium.Dimension; | |||||
import org.openqa.selenium.JavascriptExecutor; | import org.openqa.selenium.JavascriptExecutor; | ||||
import org.openqa.selenium.NoSuchElementException; | import org.openqa.selenium.NoSuchElementException; | ||||
import org.openqa.selenium.Point; | |||||
import org.openqa.selenium.WebDriver; | import org.openqa.selenium.WebDriver; | ||||
import org.openqa.selenium.WebElement; | import org.openqa.selenium.WebElement; | ||||
import org.openqa.selenium.interactions.Actions; | import org.openqa.selenium.interactions.Actions; | ||||
openTestURL(uiClass, new HashSet<>(Arrays.asList(parameters))); | openTestURL(uiClass, new HashSet<>(Arrays.asList(parameters))); | ||||
} | } | ||||
/** | |||||
* Reloads the current page, as if the user pressed F5. | |||||
*/ | |||||
protected void reloadPage() { | |||||
driver.navigate().refresh(); | |||||
} | |||||
private void openTestURL(Class<?> uiClass, Set<String> parameters) { | private void openTestURL(Class<?> uiClass, Set<String> parameters) { | ||||
String url = getTestURL(uiClass); | String url = getTestURL(uiClass); | ||||