diff options
author | Matti Tahvonen <matti@vaadin.com> | 2017-01-13 17:07:36 +0200 |
---|---|---|
committer | Pekka Hyvönen <pekka@vaadin.com> | 2017-01-13 17:07:36 +0200 |
commit | 62c44dd77e47c908361a87332182f2e2465972c0 (patch) | |
tree | 2485171f3a1326d0f7bf0a067569e535dd18d626 /uitest | |
parent | fe536b3efc4ed3d6637fead851c01375af91f762 (diff) | |
download | vaadin-framework-62c44dd77e47c908361a87332182f2e2465972c0.tar.gz vaadin-framework-62c44dd77e47c908361a87332182f2e2465972c0.zip |
Support for HTML5 push/replaceState for proper deep linking features (#8116)
* Added support for HTML5 push/replaceState for proper deep linkin features
* Automated test script now works at least on chrome
* Uses html5 push/popstate to implement uri fragment feature
* fire legacy fragment change events also via popstate events rpc calls
* send new fragments via pushstate mechanism
* formatting
* Formatting and adding test and workaround for IE bug
* Formatting and depracated UriFragmentListener
* Aligned naming in the new API
* Ignored IE due to web driver bug
Tested a workaround with javascript based window.location.href fetch,
but that don’t seem to work stable enough.
Diffstat (limited to 'uitest')
7 files changed, 197 insertions, 0 deletions
diff --git a/uitest/src/main/java/com/vaadin/tests/components/ui/PushStateAndReplaceState.java b/uitest/src/main/java/com/vaadin/tests/components/ui/PushStateAndReplaceState.java new file mode 100644 index 0000000000..22788f326c --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/ui/PushStateAndReplaceState.java @@ -0,0 +1,80 @@ +package com.vaadin.tests.components.ui; + +import java.net.URI; + +import com.vaadin.server.Page; +import com.vaadin.server.Page.PopStateEvent; +import com.vaadin.server.Page.PopStateListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractReindeerTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; + +public class PushStateAndReplaceState extends AbstractReindeerTestUI { + + private final Label locationLabel = new Label(); + private CheckBox replace; + + @Override + protected void setup(VaadinRequest request) { + locationLabel.setId("locationLabel"); + addComponent(locationLabel); + updateLabel(); + + getPage().addPopStateListener(new PopStateListener() { + + @Override + public void uriChanged(PopStateEvent event) { + Notification.show("Popstate event"); + updateLabel(); + } + }); + + replace = new CheckBox("replace"); + replace.setId("replace"); + addComponent(replace); + + addComponent(createButton("test", "Move to ./test", + Page.getCurrent().getLocation().toString() + "/test")); + addComponent(createButton("X", "Move to X", "X")); + addComponent(createButton("root_X", "Move to /X", "/X")); + } + + private Button createButton(String id, String caption, + final String newUri) { + Button button = new Button(caption, new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + if (replace.getValue()) { + getPage().replaceState(newUri); + } else { + getPage().pushState(newUri); + } + updateLabel(); + } + }); + + button.setId(id); + + return button; + } + + private void updateLabel() { + URI location = getPage().getLocation(); + locationLabel.setValue("Current Location: " + location.toString()); + } + + @Override + public String getTestDescription() { + return "Modern web framework shouldn't force you to use hashbang style urls for deep linking"; + } + + @Override + protected Integer getTicketNumber() { + return null; + } + +} diff --git a/uitest/src/main/java/com/vaadin/tests/components/ui/UriFragment.java b/uitest/src/main/java/com/vaadin/tests/components/ui/UriFragment.java index 0d0fdc4b63..61d7776439 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/ui/UriFragment.java +++ b/uitest/src/main/java/com/vaadin/tests/components/ui/UriFragment.java @@ -1,5 +1,6 @@ package com.vaadin.tests.components.ui; +import com.vaadin.server.ExternalResource; import com.vaadin.server.Page; import com.vaadin.server.Page.UriFragmentChangedEvent; import com.vaadin.server.VaadinRequest; @@ -7,6 +8,7 @@ import com.vaadin.tests.components.AbstractReindeerTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; +import com.vaadin.ui.Link; public class UriFragment extends AbstractReindeerTestUI { @@ -29,6 +31,12 @@ public class UriFragment extends AbstractReindeerTestUI { addComponent(createButton("test", "Navigate to #test", "test")); addComponent(createButton("empty", "Navigate to #", "")); addComponent(createButton("null", "setUriFragment(null)", null)); + + Link link = new Link("Navigate to #linktest", + new ExternalResource("#linktest")); + link.setId("link"); + addComponent(link); + } private Button createButton(String id, String caption, diff --git a/uitest/src/test/java/com/vaadin/tests/components/ui/PushStateAndReplaceStateTest.java b/uitest/src/test/java/com/vaadin/tests/components/ui/PushStateAndReplaceStateTest.java new file mode 100644 index 0000000000..a57cbf6ed5 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/ui/PushStateAndReplaceStateTest.java @@ -0,0 +1,69 @@ +package com.vaadin.tests.components.ui; + +import static org.junit.Assert.assertEquals; + +import java.net.URI; + +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class PushStateAndReplaceStateTest extends MultiBrowserTest { + + @Test + public void testUriFragment() throws Exception { + driver.get(getTestUrl()); + assertUri(getTestUrl()); + + hitButton("test"); + + assertUri(getTestUrl() + "/test"); + + driver.navigate().back(); + + driver.findElement(By.className("v-Notification")).getText() + .contains("Popstate event"); + + assertUri(getTestUrl()); + + hitButton("test"); + URI base = new URI(getTestUrl() + "/test"); + hitButton("X"); + URI current = base.resolve("X"); + driver.findElement(By.xpath("//*[@id = 'replace']/input")).click(); + hitButton("root_X"); + current = current.resolve("/X"); + + assertUri(current.toString()); + + // Now that last change was with replace state, two back calls should go + // to initial + driver.navigate().back(); + driver.navigate().back(); + + assertUri(getTestUrl()); + + } + + private void assertUri(String uri) { + final String expectedText = "Current Location: " + uri; + waitUntil(new ExpectedCondition<Boolean>() { + + @Override + public Boolean apply(WebDriver input) { + return expectedText.equals(getLocationLabelValue()); + } + }); + + assertEquals(uri, driver.getCurrentUrl()); + } + + private String getLocationLabelValue() { + String text = vaadinElementById("locationLabel").getText(); + return text; + } + +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/ui/UriFragmentTest.java b/uitest/src/test/java/com/vaadin/tests/components/ui/UriFragmentTest.java index e7fbf4f7ec..731573b770 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/ui/UriFragmentTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/ui/UriFragmentTest.java @@ -7,6 +7,7 @@ import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; +import com.vaadin.testbench.By; import com.vaadin.tests.tb3.MultiBrowserTest; public class UriFragmentTest extends MultiBrowserTest { @@ -42,6 +43,12 @@ public class UriFragmentTest extends MultiBrowserTest { navigateToNull(); // Setting to null when there is a fragment actually // sets it to # assertEquals("Current URI fragment:", getFragmentLabelValue()); + + // ensure IE works with new popstate based implementation, see + // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/3740423/ + driver.findElement(By.xpath("//*[@id = 'link']/a")).click(); + assertFragment("linktest"); + } private void assertFragment(String fragment) { diff --git a/uitest/src/test/java/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java b/uitest/src/test/java/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java index 11848344ba..4507c12cfe 100644 --- a/uitest/src/test/java/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java +++ b/uitest/src/test/java/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java @@ -17,15 +17,26 @@ package com.vaadin.tests.navigator; import static org.junit.Assert.assertEquals; +import java.util.List; + import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.tests.tb3.MultiBrowserTest; public class NavigatorViewBlocksBackButtonActionTest extends MultiBrowserTest { + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // IE web driver fails to read fragment properly, these must be tested + // manually. See + // https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/7966 + return getBrowsersExcludingIE(); + } + @Test public void testIfConfirmBack() { openTestURL(); diff --git a/uitest/src/test/java/com/vaadin/tests/urifragments/FragmentHandlingAndAsynchUIUpdateTest.java b/uitest/src/test/java/com/vaadin/tests/urifragments/FragmentHandlingAndAsynchUIUpdateTest.java index 4da3ae1541..13b18de516 100644 --- a/uitest/src/test/java/com/vaadin/tests/urifragments/FragmentHandlingAndAsynchUIUpdateTest.java +++ b/uitest/src/test/java/com/vaadin/tests/urifragments/FragmentHandlingAndAsynchUIUpdateTest.java @@ -18,9 +18,12 @@ package com.vaadin.tests.urifragments; import static com.vaadin.tests.urifragments.FragmentHandlingAndAsynchUIUpdate.FRAG_NAME_TPL; import static com.vaadin.tests.urifragments.FragmentHandlingAndAsynchUIUpdate.START_FRAG_ID; +import java.util.List; + import org.junit.Test; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; +import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.By; @@ -33,6 +36,14 @@ import com.vaadin.tests.tb3.MultiBrowserTest; */ public class FragmentHandlingAndAsynchUIUpdateTest extends MultiBrowserTest { + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // IE web driver fails to read fragment properly, these must be tested + // manually. See + // https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/7966 + return getBrowsersExcludingIE(); + } + /** * The case when we successively set 10 fragments, go back 9 times and then * go forward 9 times diff --git a/uitest/src/test/java/com/vaadin/tests/urifragments/SettingNullFragmentTest.java b/uitest/src/test/java/com/vaadin/tests/urifragments/SettingNullFragmentTest.java index db700b4393..f728be937a 100644 --- a/uitest/src/test/java/com/vaadin/tests/urifragments/SettingNullFragmentTest.java +++ b/uitest/src/test/java/com/vaadin/tests/urifragments/SettingNullFragmentTest.java @@ -15,8 +15,11 @@ */ package com.vaadin.tests.urifragments; +import java.util.List; + import org.junit.Test; import org.openqa.selenium.WebDriver; +import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -29,6 +32,14 @@ import com.vaadin.tests.tb3.MultiBrowserTest; */ public class SettingNullFragmentTest extends MultiBrowserTest { + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // IE web driver fails to read fragment properly, these must be tested + // manually. See + // https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/7966 + return getBrowsersExcludingIE(); + } + @Test public void testSettingNullURIFragment() throws Exception { openTestURL(); |