diff options
author | Teemu Suo-Anttila <tsuoanttila@users.noreply.github.com> | 2017-10-13 09:44:32 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-13 09:44:32 +0300 |
commit | 569072dccd09a018850abb3a7f9d39373c082d4f (patch) | |
tree | 03b19813308487fa1f83437edc0f75ee692511dc /test/spring-boot-subcontext | |
parent | c147b5d85bca3ddf30d9adbcd268066165889f37 (diff) | |
download | vaadin-framework-569072dccd09a018850abb3a7f9d39373c082d4f.tar.gz vaadin-framework-569072dccd09a018850abb3a7f9d39373c082d4f.zip |
Add Navigator testing to Spring Boot test (#10174)
Diffstat (limited to 'test/spring-boot-subcontext')
16 files changed, 584 insertions, 0 deletions
diff --git a/test/spring-boot-subcontext/pom.xml b/test/spring-boot-subcontext/pom.xml new file mode 100644 index 0000000000..0a8bc052df --- /dev/null +++ b/test/spring-boot-subcontext/pom.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.2-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-spring-boot-subcontext</artifactId> + <packaging>jar</packaging> + + <name>vaadin-test-spring-boot-subcontext</name> + <description>Demo project for Vaadin Spring Boot</description> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <java.version>1.8</java.version> + <spring.boot.version>1.4.2.RELEASE</spring.boot.version> + <jetty.skip>true</jetty.skip> + </properties> + + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-bom</artifactId> + <version>${vaadin.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <type>pom</type> + <scope>import</scope> + <version>${spring.boot.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>${spring.boot.version}</version> + </plugin> + </plugins> + </build> + +</project> diff --git a/test/spring-boot-subcontext/src/main/java/com/example/CustomSpringNavigator.java b/test/spring-boot-subcontext/src/main/java/com/example/CustomSpringNavigator.java new file mode 100644 index 0000000000..fd11bb1473 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/CustomSpringNavigator.java @@ -0,0 +1,19 @@ +package com.example; + +import org.springframework.stereotype.Component; + +import com.vaadin.navigator.ViewDisplay; +import com.vaadin.spring.annotation.UIScope; +import com.vaadin.spring.navigator.SpringNavigator; +import com.vaadin.ui.UI; + +@UIScope +@Component +public class CustomSpringNavigator extends SpringNavigator { + + @Override + public void init(UI ui, ViewDisplay display) { + // FIXME: Should be in Spring plug-in + init(ui, null, display); + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/DemoApplication.java b/test/spring-boot-subcontext/src/main/java/com/example/DemoApplication.java new file mode 100644 index 0000000000..81af148442 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/DemoApplication.java @@ -0,0 +1,25 @@ +package com.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; + +import com.vaadin.spring.server.SpringVaadinServlet; + +@SpringBootApplication +public class DemoApplication { + + public static final String CONTEXT = "/subcontext"; + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + + @Bean + ServletRegistrationBean servlet() { + return new ServletRegistrationBean(new SpringVaadinServlet(), false, + CONTEXT + "/*", "/VAADIN/*"); + } + +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/ThankYouService.java b/test/spring-boot-subcontext/src/main/java/com/example/ThankYouService.java new file mode 100644 index 0000000000..b387046659 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/ThankYouService.java @@ -0,0 +1,13 @@ +package com.example; + +import org.springframework.stereotype.Service; + +@Service +public class ThankYouService { + + public static final String THANK_YOU_TEXT = "Thank you for clicking."; + + public String getText() { + return THANK_YOU_TEXT; + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/ViewGreeter.java b/test/spring-boot-subcontext/src/main/java/com/example/ViewGreeter.java new file mode 100644 index 0000000000..54d60d2d9c --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/ViewGreeter.java @@ -0,0 +1,13 @@ +package com.example; + +import com.vaadin.spring.annotation.SpringComponent; + +@SpringComponent +public class ViewGreeter { + private int counter = 0; + + public String sayHello() { + return "Hello number " + counter++ + + " from bean with same scope as view " + toString(); + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/ui/AbstractSpringUI.java b/test/spring-boot-subcontext/src/main/java/com/example/ui/AbstractSpringUI.java new file mode 100644 index 0000000000..2549e7e8a8 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/ui/AbstractSpringUI.java @@ -0,0 +1,62 @@ +package com.example.ui; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.example.view.DefaultView; +import com.example.view.UIScopedView; +import com.example.view.ViewDisplayPanel; +import com.example.view.ViewScopedView; +import com.vaadin.server.VaadinRequest; +import com.vaadin.spring.annotation.SpringUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +abstract class AbstractSpringUI extends UI { + + @Autowired + private ViewDisplayPanel springViewDisplay; + protected CssLayout navigationBar; + + @Override + protected void init(VaadinRequest request) { + final VerticalLayout root = new VerticalLayout(); + root.setSizeFull(); + root.setMargin(true); + root.setSpacing(true); + setContent(root); + + navigationBar = new CssLayout(); + navigationBar.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); + navigationBar.addComponent( + createNavigationButton("Default View", DefaultView.VIEW_NAME)); + navigationBar.addComponent(createNavigationButton("UI Scoped View", + UIScopedView.VIEW_NAME)); + navigationBar.addComponent(createNavigationButton("View Scoped View", + ViewScopedView.VIEW_NAME)); + root.addComponent(navigationBar); + + root.addComponent(springViewDisplay); + root.setExpandRatio(springViewDisplay, 1.0f); + + } + + private Button createNavigationButton(String caption, + final String viewName) { + Button button = new Button(caption); + button.setId(viewName + "-button"); + button.addStyleName(ValoTheme.BUTTON_SMALL); + button.addClickListener( + event -> getUI().getNavigator().navigateTo(viewName)); + return button; + } + + @Override + public String getUiRootPath() { + // FIXME: Should be handled by Spring plug-in + return super.getUiRootPath() + "/" + + getClass().getAnnotation(SpringUI.class).path(); + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/ui/RootPathUI.java b/test/spring-boot-subcontext/src/main/java/com/example/ui/RootPathUI.java new file mode 100644 index 0000000000..1ed2725c42 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/ui/RootPathUI.java @@ -0,0 +1,18 @@ +package com.example.ui; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.spring.annotation.SpringUI; +import com.vaadin.ui.Label; + +@SpringUI +public class RootPathUI extends AbstractSpringUI { + + @Override + protected void init(VaadinRequest request) { + super.init(request); + + Label label = new Label("RootPathUI"); + label.setId("rootpath"); + navigationBar.addComponent(label); + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/ui/SubPathUI.java b/test/spring-boot-subcontext/src/main/java/com/example/ui/SubPathUI.java new file mode 100644 index 0000000000..605d771d52 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/ui/SubPathUI.java @@ -0,0 +1,22 @@ +package com.example.ui; + +import com.vaadin.navigator.PushStateNavigation; +import com.vaadin.server.VaadinRequest; +import com.vaadin.spring.annotation.SpringUI; +import com.vaadin.ui.Label; + +@PushStateNavigation +@SpringUI(path = SubPathUI.SUBPATH) +public class SubPathUI extends AbstractSpringUI { + + public static final String SUBPATH = "subpath"; + + @Override + protected void init(VaadinRequest request) { + super.init(request); + + Label label = new Label("SubPathUI"); + label.setId(SUBPATH); + navigationBar.addComponent(label); + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/view/DefaultView.java b/test/spring-boot-subcontext/src/main/java/com/example/view/DefaultView.java new file mode 100644 index 0000000000..7fe9572e3e --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/view/DefaultView.java @@ -0,0 +1,33 @@ +package com.example.view; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.example.ThankYouService; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.spring.annotation.SpringView; +import com.vaadin.ui.Button; +import com.vaadin.ui.Notification; +import com.vaadin.ui.VerticalLayout; + +@SpringView(name = DefaultView.VIEW_NAME) +public class DefaultView extends VerticalLayout implements View { + public static final String VIEW_NAME = ""; + + @Autowired + private ThankYouService service; + + @PostConstruct + void init() { + setId("default-view"); + Button button = new Button("Click Me!", + e -> Notification.show(service.getText())); + addComponent(button); + } + + @Override + public void enter(ViewChangeEvent event) { + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/view/UIScopedView.java b/test/spring-boot-subcontext/src/main/java/com/example/view/UIScopedView.java new file mode 100644 index 0000000000..e3a5aa57d0 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/view/UIScopedView.java @@ -0,0 +1,35 @@ +package com.example.view; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.example.ViewGreeter; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.spring.annotation.SpringView; +import com.vaadin.spring.annotation.UIScope; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +@UIScope +@SpringView(name = UIScopedView.VIEW_NAME) +public class UIScopedView extends VerticalLayout implements View { + public static final String VIEW_NAME = "ui-scoped"; + + @Autowired + ViewGreeter service; + + @PostConstruct + void init() { + setId(VIEW_NAME); + setMargin(true); + setSpacing(true); + addComponents(new Label("This is a UI scoped view."), + new Label(service.sayHello())); + } + + @Override + public void enter(ViewChangeEvent event) { + } +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/view/ViewDisplayPanel.java b/test/spring-boot-subcontext/src/main/java/com/example/view/ViewDisplayPanel.java new file mode 100644 index 0000000000..ab4f5ffda8 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/view/ViewDisplayPanel.java @@ -0,0 +1,26 @@ +package com.example.view; + +import javax.annotation.PostConstruct; + +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewDisplay; +import com.vaadin.spring.annotation.SpringViewDisplay; +import com.vaadin.spring.annotation.UIScope; +import com.vaadin.ui.Component; +import com.vaadin.ui.Panel; + +@UIScope +@SpringViewDisplay +public class ViewDisplayPanel extends Panel implements ViewDisplay { + + @PostConstruct + void init() { + setSizeFull(); + } + + @Override + public void showView(View view) { + setContent((Component) view); + } + +} diff --git a/test/spring-boot-subcontext/src/main/java/com/example/view/ViewScopedView.java b/test/spring-boot-subcontext/src/main/java/com/example/view/ViewScopedView.java new file mode 100644 index 0000000000..33b0a553cc --- /dev/null +++ b/test/spring-boot-subcontext/src/main/java/com/example/view/ViewScopedView.java @@ -0,0 +1,34 @@ +package com.example.view; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.example.ViewGreeter; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.spring.annotation.SpringView; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +@SpringView(name = ViewScopedView.VIEW_NAME) +public class ViewScopedView extends VerticalLayout implements View { + public static final String VIEW_NAME = "view-scoped"; + + @Autowired + ViewGreeter service; + + @PostConstruct + void init() { + setId(VIEW_NAME); + setMargin(true); + setSpacing(true); + addComponents(new Label("This is a view scoped view"), + new Label(service.sayHello())); + + } + + @Override + public void enter(ViewChangeEvent event) { + } +} diff --git a/test/spring-boot-subcontext/src/main/resources/application.properties b/test/spring-boot-subcontext/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/spring-boot-subcontext/src/main/resources/application.properties diff --git a/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootPushStateNavigatorIT.java b/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootPushStateNavigatorIT.java new file mode 100644 index 0000000000..41692789f7 --- /dev/null +++ b/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootPushStateNavigatorIT.java @@ -0,0 +1,25 @@ +package com.example; + +import org.junit.Ignore; +import org.junit.Test; + +public class VaadinSpringBootPushStateNavigatorIT + extends VaadinSpringBootURIFragmentNavigatorIT { + + @Ignore("PushState navigation is partially broken with Spring.") + @Override + @Test + public void testNotDefaultView() { + super.testNotDefaultView(); + } + + @Override + protected String getPath() { + return "subpath"; + } + + @Override + protected String getViewSeparator() { + return "/"; + } +} diff --git a/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootSmokeIT.java b/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootSmokeIT.java new file mode 100644 index 0000000000..f6f3db6243 --- /dev/null +++ b/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootSmokeIT.java @@ -0,0 +1,61 @@ +package com.example; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.phantomjs.PhantomJSDriver; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.example.ui.SubPathUI; +import com.vaadin.testbench.ScreenshotOnFailureRule; +import com.vaadin.testbench.TestBench; +import com.vaadin.testbench.TestBenchTestCase; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.testbench.elements.PanelElement; +import com.vaadin.testbench.parallel.Browser; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class VaadinSpringBootSmokeIT extends TestBenchTestCase { + + @Rule + public ScreenshotOnFailureRule screenshotRule = new ScreenshotOnFailureRule( + this, true); + + @LocalServerPort + Integer port; + + @Before + public void setUp() { + setDriver(TestBench.createDriver(new PhantomJSDriver( + Browser.PHANTOMJS.getDesiredCapabilities()))); + } + + @Test + public void testPageLoadsAndButtonWorks() { + getDriver().navigate() + .to("http://localhost:" + port + "/" + DemoApplication.CONTEXT); + runSmokeTest(); + } + + @Test + public void testSubPathPageLoadsAndButtonWorks() { + getDriver().navigate().to("http://localhost:" + port + "/" + + DemoApplication.CONTEXT + "/" + SubPathUI.SUBPATH); + runSmokeTest(); + } + + private void runSmokeTest() { + $(ButtonElement.class).in($(PanelElement.class)).first().click(); + + Assert.assertTrue($(NotificationElement.class).exists()); + Assert.assertEquals(ThankYouService.THANK_YOU_TEXT, + $(NotificationElement.class).first().getText()); + } +} diff --git a/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootURIFragmentNavigatorIT.java b/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootURIFragmentNavigatorIT.java new file mode 100644 index 0000000000..c7c4d0a1db --- /dev/null +++ b/test/spring-boot-subcontext/src/test/java/com/example/VaadinSpringBootURIFragmentNavigatorIT.java @@ -0,0 +1,132 @@ +package com.example; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.phantomjs.PhantomJSDriver; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.example.view.DefaultView; +import com.example.view.UIScopedView; +import com.example.view.ViewScopedView; +import com.vaadin.testbench.ScreenshotOnFailureRule; +import com.vaadin.testbench.TestBench; +import com.vaadin.testbench.TestBenchTestCase; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.parallel.Browser; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class VaadinSpringBootURIFragmentNavigatorIT extends TestBenchTestCase { + + @Rule + public ScreenshotOnFailureRule screenshotRule = new ScreenshotOnFailureRule( + this, true); + + private String currentUIPath; + + @LocalServerPort + Integer port; + + @Before + public void setUp() { + setDriver(TestBench.createDriver(new PhantomJSDriver( + Browser.PHANTOMJS.getDesiredCapabilities()))); + } + + @Test + public void testUINavigation() { + currentUIPath = "http://localhost:" + port + DemoApplication.CONTEXT + + "/" + getPath(); + + runNavigationTestPattern(); + } + + @Test + public void testNotDefaultView() { + currentUIPath = "http://localhost:" + port + DemoApplication.CONTEXT + + "/" + getPath(); + getDriver().navigate().to( + currentUIPath + getViewSeparator() + ViewScopedView.VIEW_NAME); + + verifyViewScopeViewOpen(); + } + + private void runNavigationTestPattern() { + getDriver().navigate().to(currentUIPath); + + verifyDefaultViewOpen(""); + + openView(UIScopedView.VIEW_NAME); + verifyUIScopedViewOpen(); + + openView(ViewScopedView.VIEW_NAME); + verifyViewScopeViewOpen(); + + openView(DefaultView.VIEW_NAME); + verifyDefaultViewOpen(getViewSeparator()); + + getDriver().navigate().back(); + verifyViewScopeViewOpen(); + + getDriver().navigate().back(); + verifyUIScopedViewOpen(); + + getDriver().navigate().back(); + verifyDefaultViewOpen(""); + + getDriver().navigate().forward(); + verifyUIScopedViewOpen(); + + getDriver().navigate().forward(); + verifyViewScopeViewOpen(); + } + + private void verifyDefaultViewOpen(String viewIdentifier) { + verifyViewOpen("default-view"); + verifyURL(currentUIPath + viewIdentifier); + } + + private void verifyViewScopeViewOpen() { + verifyViewOpen(ViewScopedView.VIEW_NAME); + verifyURL( + currentUIPath + getViewSeparator() + ViewScopedView.VIEW_NAME); + } + + private void verifyUIScopedViewOpen() { + verifyViewOpen(UIScopedView.VIEW_NAME); + verifyURL(currentUIPath + getViewSeparator() + UIScopedView.VIEW_NAME); + } + + private void verifyViewOpen(String viewName) { + try { + findElement(By.id(viewName)); + } catch (NoSuchElementException e) { + Assert.fail( + "View <" + viewName + "> was not open, no element found"); + } + } + + private void verifyURL(String url) { + Assert.assertEquals("Invalid URL", url, getDriver().getCurrentUrl()); + } + + private void openView(String viewName) { + $(ButtonElement.class).id(viewName + "-button").click(); + } + + protected String getPath() { + return ""; + } + + protected String getViewSeparator() { + return "#!"; + } +} |