Skip to content

Commit

Permalink
Add IT test for service worker and runtime
Browse files Browse the repository at this point in the history
Fixes #2867
  • Loading branch information
krissvaa committed Nov 13, 2024
1 parent 3ba43b0 commit 2654b66
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/java/tests/spring/runtime/frontend/about-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';

@customElement('about-view')
export class AboutView extends LitElement {
render() {
return html` <div>About</div> `;
}
}
25 changes: 25 additions & 0 deletions packages/java/tests/spring/runtime/frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!doctype html>
<!--
This file is auto-generated by Vaadin.
-->

<html lang="en">
<head>
<title>ITs for Endpoints</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body,
#outlet {
height: 100vh;
width: 100%;
margin: 0;
}
</style>
<!-- index.ts is included here automatically (either by the dev server or during the build) -->
</head>
<body>
<!-- This outlet div is where the views are rendered -->
<div id="outlet"></div>
</body>
</html>
10 changes: 10 additions & 0 deletions packages/java/tests/spring/runtime/frontend/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import './test-view.js';
import './about-view.js';
import { Route, Router } from '@vaadin/router';

const routes: Route[] = [{ path: '/', component: 'test-view' },
{ path: '/about-view', component: 'about-view' }];

// Vaadin router needs an outlet in the index.html page to display views
const router = new Router(document.querySelector('#outlet'));
router.setRoutes(routes);
9 changes: 9 additions & 0 deletions packages/java/tests/spring/runtime/frontend/test-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';

@customElement('test-view')
export class TestView extends LitElement {
render() {
return html` <div>Hello</div> `;
}
}
49 changes: 49 additions & 0 deletions packages/java/tests/spring/runtime/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?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>tests-spring</artifactId>
<version>24.6-SNAPSHOT</version>
</parent>

<artifactId>tests-hilla-runtime</artifactId>

<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<formatter.basedir>${project.parent.parent.parent.basedir}</formatter.basedir>
</properties>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>hilla</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<defaultGoal>spring-boot:run</defaultGoal>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>hilla-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.vaadin.flow.connect;

import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.server.PWA;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* The entry point of the Spring Boot application.
*/
@SpringBootApplication
@PWA(name = "My App", shortName = "app")
public class Application implements AppShellConfigurator {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.vaadin.flow.connect;

import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends VaadinWebSecurity {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf(h -> h.ignoringRequestMatchers(new AntPathRequestMatcher("/login")));
http.authorizeHttpRequests(
h -> h.requestMatchers(new AntPathRequestMatcher("/"))
.permitAll());
http.authorizeHttpRequests(
h -> h.requestMatchers(new AntPathRequestMatcher("/about-view"))
.permitAll());
super.configure(http);
setLoginView(http, "/login");
}

@Bean
public InMemoryUserDetailsManager userDetailsService() {
// Configure users and roles in memory
UserDetails user = User.withUsername("user").password("{noop}user")
.roles("USER").build();
UserDetails admin = User.withUsername("admin").password("{noop}admin")
.roles("ADMIN", "USER").build();
return new InMemoryUserDetailsManager(user, admin);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
server.port=8888
vaadin.devmode.liveReload.enabled=false
logging.level.org.atmosphere = warn
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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.connect;

import com.vaadin.flow.testutil.ChromeDeviceTest;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;

public class ServiceWorkerIT extends ChromeDeviceTest {

@Test
public void onlineRoot_serviceWorkerInstalled_serviceWorkerActive() {
getDriver().get(getRootURL() + "/");
waitForDevServer();
waitForServiceWorkerReady();

boolean serviceWorkerActive = (boolean) ((JavascriptExecutor) getDriver())
.executeAsyncScript(
"const resolve = arguments[arguments.length - 1];"
+ "navigator.serviceWorker.ready.then( function(reg) { resolve(!!reg.active); });");
Assert.assertTrue("service worker not installed", serviceWorkerActive);
}

@Test
public void offlineRoot_reload_viewReloaded() {
openPageAndPreCacheWhenDevelopmentMode("/");

// Confirm that app shell is loaded
Assert.assertNotNull("Should have outlet when loaded online",
findElement(By.id("outlet")));

// Confirm that client side view is loaded
Assert.assertNotNull(
"Should have <test-view> in DOM when loaded online",
findElement(By.tagName("test-view")));

// Reload the page in offline mode
executeScript("window.location.reload();");
waitUntil(webDriver -> ((JavascriptExecutor) driver)
.executeScript("return document.readyState")
.equals("complete"));
}

private void openPageAndPreCacheWhenDevelopmentMode(String targetView) {
openPageAndPreCacheWhenDevelopmentMode(targetView, () -> {
});
}

private void openPageAndPreCacheWhenDevelopmentMode(String targetView,
Runnable activateViews) {
getDriver().get(getRootURL() + targetView);
waitForDevServer();
waitForServiceWorkerReady();

boolean isDevMode = Boolean.getBoolean("vaadin.test.developmentMode");
if (isDevMode) {
// In production mode all views are supposed to be already in the
// bundle, but in dev mode they are loaded at runtime
// So, for dev mode, pre cache required views
activateViews.run();

// In addition not all external resources are cached when the page
// opens
// first time, so we need to reload the page even if there is no
// navigation to other views
getDriver().get(getRootURL() + targetView);
waitForDevServer();
waitForServiceWorkerReady();
}
}

@Override
protected String getRootURL() {
return super.getRootURL();
}
}

0 comments on commit 2654b66

Please sign in to comment.