diff --git a/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java b/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java index 0090effcc0e..f8ebb87d999 100644 --- a/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java +++ b/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java @@ -286,7 +286,8 @@ protected void pushHistoryState(NavigationEvent event) { } protected boolean shouldPushHistoryState(NavigationEvent event) { - return NavigationTrigger.UI_NAVIGATE.equals(event.getTrigger()); + return NavigationTrigger.UI_NAVIGATE.equals(event.getTrigger()) + || NavigationTrigger.REFRESH.equals(event.getTrigger()); } private boolean isRouterLinkNotFoundNavigationError( diff --git a/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/PreserveOnRefreshNavigationView.java b/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/PreserveOnRefreshNavigationView.java new file mode 100644 index 00000000000..50e39b96887 --- /dev/null +++ b/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/PreserveOnRefreshNavigationView.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2024 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.flow.uitest.ui; + +import com.vaadin.flow.component.UI; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.component.html.NativeButton; +import com.vaadin.flow.dom.Element; +import com.vaadin.flow.dom.ElementFactory; +import com.vaadin.flow.router.PreserveOnRefresh; +import com.vaadin.flow.router.QueryParameters; +import com.vaadin.flow.router.Route; + +@Route(value = PreserveOnRefreshNavigationView.VIEW_PATH) +@PreserveOnRefresh +public class PreserveOnRefreshNavigationView extends Div { + + static final String VIEW_PATH = "com.vaadin.flow.uitest.ui.PreserveOnRefreshNavigationView"; + + public PreserveOnRefreshNavigationView() { + add(createNavigationButton("one")); + add(createNavigationButton("two")); + add(createNavigationButton("three")); + + getElement().appendChild(createRouterLink("one"), + createRouterLink("two"), createRouterLink("three")); + } + + private NativeButton createNavigationButton(String param) { + NativeButton button = new NativeButton("navigate to " + param, + ev -> selfNavigate(param)); + button.setId("button-" + param); + return button; + } + + private void selfNavigate(String param) { + UI.getCurrent().navigate(PreserveOnRefreshNavigationView.class, + QueryParameters.of("param", param)); + } + + private Element createRouterLink(String param) { + Element routerLink = ElementFactory.createRouterLink( + VIEW_PATH + "?param=" + param, "link to " + param); + routerLink.setAttribute("id", "link-" + param); + return routerLink; + } +} diff --git a/flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/PreserveOnRefreshNavigationIT.java b/flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/PreserveOnRefreshNavigationIT.java new file mode 100644 index 00000000000..1cecb84770d --- /dev/null +++ b/flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/PreserveOnRefreshNavigationIT.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2024 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.flow.uitest.ui; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.flow.testutil.ChromeBrowserTest; +import com.vaadin.testbench.TestBenchElement; + +public class PreserveOnRefreshNavigationIT extends ChromeBrowserTest { + + @Test + public void routerLink_selfNavigationWithQueryParams_urlChanges() { + open(); + $(TestBenchElement.class).id("link-one").click(); + Assert.assertTrue(driver.getCurrentUrl().contains("?param=one")); + $(TestBenchElement.class).id("link-two").click(); + Assert.assertTrue(driver.getCurrentUrl().contains("?param=two")); + $(TestBenchElement.class).id("link-three").click(); + Assert.assertTrue(driver.getCurrentUrl().contains("?param=three")); + } + + @Test + public void programmaticNavigation_selfNavigationWithQueryParams_urlChanges() { + open(); + $(TestBenchElement.class).id("button-one").click(); + Assert.assertTrue(driver.getCurrentUrl().contains("?param=one")); + $(TestBenchElement.class).id("button-two").click(); + Assert.assertTrue(driver.getCurrentUrl().contains("?param=two")); + $(TestBenchElement.class).id("button-three").click(); + Assert.assertTrue(driver.getCurrentUrl().contains("?param=three")); + } + +}