@@ -109,6 +109,7 @@ | |||
<module>space in directory</module> | |||
<module>vaadinservletconfiguration-widget-set</module> | |||
<module>spring-boot</module> | |||
<module>spring-boot-subcontext</module> | |||
<module>cdi</module> | |||
<!-- Servlet container tests --> |
@@ -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> |
@@ -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); | |||
} | |||
} |
@@ -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/*"); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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) { | |||
} | |||
} |
@@ -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) { | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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) { | |||
} | |||
} |
@@ -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 "/"; | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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 "#!"; | |||
} | |||
} |
@@ -19,6 +19,7 @@ | |||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
<java.version>1.8</java.version> | |||
<spring.boot.version>1.5.1.RELEASE</spring.boot.version> | |||
<jetty.skip>true</jetty.skip> | |||
</properties> | |||
<dependencies> | |||
@@ -59,23 +60,6 @@ | |||
<artifactId>spring-boot-maven-plugin</artifactId> | |||
<version>${spring.boot.version}</version> | |||
</plugin> | |||
<!-- Disable jetty-plugin --> | |||
<plugin> | |||
<groupId>org.eclipse.jetty</groupId> | |||
<artifactId>jetty-maven-plugin</artifactId> | |||
<version>${jetty.version}</version> | |||
<executions> | |||
<execution> | |||
<id>start-jetty</id> | |||
<phase /> | |||
</execution> | |||
<execution> | |||
<id>stop-jetty</id> | |||
<phase /> | |||
</execution> | |||
</executions> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
@@ -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); | |||
} | |||
} |
@@ -1,32 +1,13 @@ | |||
package com.example; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.boot.SpringApplication; | |||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.spring.annotation.SpringUI; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Notification; | |||
import com.vaadin.ui.UI; | |||
@SpringBootApplication | |||
public class DemoApplication { | |||
public static void main(String[] args) { | |||
SpringApplication.run(DemoApplication.class, args); | |||
} | |||
} | |||
@SpringUI | |||
class MyUI extends UI { | |||
@Autowired | |||
ThankYouService service; | |||
@Override | |||
protected void init(VaadinRequest request) { | |||
setContent(new Button("Click Me!", | |||
e -> Notification.show(service.getText()))); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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) { | |||
} | |||
} |
@@ -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) { | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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) { | |||
} | |||
} |
@@ -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 "/"; | |||
} | |||
} |
@@ -1,8 +1,6 @@ | |||
package com.example; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertTrue; | |||
import org.junit.Assert; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
@@ -13,17 +11,15 @@ 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; | |||
/** | |||
* @author Vaadin Ltd | |||
* | |||
*/ | |||
@RunWith(SpringJUnit4ClassRunner.class) | |||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) | |||
public class VaadinSpringBootSmokeIT extends TestBenchTestCase { | |||
@@ -44,9 +40,21 @@ public class VaadinSpringBootSmokeIT extends TestBenchTestCase { | |||
@Test | |||
public void testPageLoadsAndButtonWorks() { | |||
getDriver().navigate().to("http://localhost:" + port + ""); | |||
$(ButtonElement.class).first().click(); | |||
assertTrue($(NotificationElement.class).exists()); | |||
assertEquals(ThankYouService.THANK_YOU_TEXT, | |||
runSmokeTest(); | |||
} | |||
@Test | |||
public void testSubPathPageLoadsAndButtonWorks() { | |||
getDriver().navigate() | |||
.to("http://localhost:" + port + "/" + 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()); | |||
} | |||
} |
@@ -0,0 +1,130 @@ | |||
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 + "/" + getPath(); | |||
runNavigationTestPattern(); | |||
} | |||
@Test | |||
public void testNotDefaultView() { | |||
currentUIPath = "http://localhost:" + port + "/" + 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 "#!"; | |||
} | |||
} |