Skip to content

Commit f1479d8

Browse files
javier-godoyscardanzan
authored andcommitted
feat: add a target that will be used as the display location for the timer allowing the timer to keep running even when the time is not shown
1 parent a8e0734 commit f1479d8

File tree

13 files changed

+603
-51
lines changed

13 files changed

+603
-51
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
/.project
55
/node_modules
66
/webpack.generated.js
7+
/webpack.config.js
78
/node
89
/package.json
910
/package-lock.json
11+
/frontend/index.html
12+
/frontend/generated
13+
/error-screenshots

pom.xml

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<description>Simple Timer for Vaadin Flow</description>
1010

1111
<properties>
12-
<vaadin.version>14.11.12</vaadin.version>
12+
<vaadin.version>14.11.13</vaadin.version>
1313
<maven.compiler.source>1.8</maven.compiler.source>
1414
<maven.compiler.target>1.8</maven.compiler.target>
1515
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -143,6 +143,34 @@
143143
<type>jar</type>
144144
<scope>test</scope>
145145
</dependency>
146+
<dependency>
147+
<groupId>com.vaadin</groupId>
148+
<artifactId>vaadin-testbench</artifactId>
149+
<scope>test</scope>
150+
</dependency>
151+
<dependency>
152+
<groupId>com.vaadin</groupId>
153+
<artifactId>license-checker</artifactId>
154+
<scope>test</scope>
155+
</dependency>
156+
<dependency>
157+
<groupId>org.hamcrest</groupId>
158+
<artifactId>hamcrest-library</artifactId>
159+
<version>1.3</version>
160+
<scope>test</scope>
161+
</dependency>
162+
<dependency>
163+
<groupId>io.github.bonigarcia</groupId>
164+
<artifactId>webdrivermanager</artifactId>
165+
<version>5.9.1</version>
166+
<scope>test</scope>
167+
</dependency>
168+
<dependency>
169+
<groupId>com.flowingcode.vaadin.test</groupId>
170+
<artifactId>testbench-rpc</artifactId>
171+
<version>1.3.0</version>
172+
<scope>test</scope>
173+
</dependency>
146174
</dependencies>
147175

148176
<build>
@@ -238,6 +266,89 @@
238266
</build>
239267

240268
<profiles>
269+
<profile>
270+
<id>it</id>
271+
<build>
272+
<plugins>
273+
<plugin>
274+
<groupId>org.eclipse.jetty</groupId>
275+
<artifactId>jetty-maven-plugin</artifactId>
276+
<version>${jetty.version}</version>
277+
<configuration>
278+
<scanIntervalSeconds>0</scanIntervalSeconds>
279+
<supportedPackagings>
280+
<supportedPackaging>jar</supportedPackaging>
281+
</supportedPackagings>
282+
<stopKey>${project.artifactId}</stopKey>
283+
<stopPort>8081</stopPort>
284+
</configuration>
285+
<executions>
286+
<execution>
287+
<id>start-jetty</id>
288+
<phase>pre-integration-test</phase>
289+
<goals>
290+
<goal>start</goal>
291+
</goals>
292+
</execution>
293+
<execution>
294+
<id>stop-jetty</id>
295+
<phase>post-integration-test</phase>
296+
<goals>
297+
<goal>stop</goal>
298+
</goals>
299+
</execution>
300+
</executions>
301+
</plugin>
302+
<plugin>
303+
<groupId>org.apache.maven.plugins</groupId>
304+
<artifactId>maven-failsafe-plugin</artifactId>
305+
<version>2.22.2</version>
306+
<executions>
307+
<execution>
308+
<goals>
309+
<goal>integration-test</goal>
310+
<goal>verify</goal>
311+
</goals>
312+
</execution>
313+
</executions>
314+
<configuration>
315+
<trimStackTrace>false</trimStackTrace>
316+
<enableAssertions>true</enableAssertions>
317+
<systemPropertyVariables>
318+
<!-- Pass location of downloaded webdrivers to the tests -->
319+
<webdriver.chrome.driver>
320+
${webdriver.chrome.driver}
321+
</webdriver.chrome.driver>
322+
</systemPropertyVariables>
323+
</configuration>
324+
</plugin>
325+
<plugin>
326+
<artifactId>maven-resources-plugin</artifactId>
327+
<version>3.1.0</version>
328+
<executions>
329+
<execution>
330+
<!-- Since the view class is defined in test, after compilation copy
331+
it to the runtime classpath to ensure it gets visited by vaadin-maven-plugin -->
332+
<id>copy-test-to-classes</id>
333+
<phase>process-test-classes</phase>
334+
<goals>
335+
<goal>copy-resources</goal>
336+
</goals>
337+
<configuration>
338+
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
339+
<resources>
340+
<resource>
341+
<directory>${project.build.testOutputDirectory}</directory>
342+
</resource>
343+
</resources>
344+
</configuration>
345+
</execution>
346+
</executions>
347+
</plugin>
348+
</plugins>
349+
</build>
350+
</profile>
351+
241352
<profile>
242353
<id>directory</id>
243354
<build>

src/main/java/com/flowingcode/vaadin/addons/simpletimer/SimpleTimer.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ public void setDoubleDigitHours(final boolean doubleDigitHours) {
109109
getElement().setProperty("doubleDigitHours", doubleDigitHours);
110110
}
111111

112+
public void setTargetId(final String targetId) {
113+
getElement().setProperty("targetId", targetId);
114+
}
115+
112116
/** Starts or stops the timer if it is already started */
113117
public void start() {
114118
getElement().callJsFunction("start");
@@ -167,8 +171,8 @@ public CompletableFuture<BigDecimal> getCurrentTimeAsync() {
167171
* @return this registration, for chaining
168172
*/
169173
public Registration addCurrentTimeChangeListener(
170-
PropertyChangeListener listener, long period, TimeUnit periodUnit) {
171-
int millis = (int) Math.min(periodUnit.toMillis(period), Integer.MAX_VALUE);
174+
PropertyChangeListener listener, final long period, final TimeUnit periodUnit) {
175+
final int millis = (int) Math.min(periodUnit.toMillis(period), Integer.MAX_VALUE);
172176
if (listener == null) {
173177
listener = ev -> {};
174178
}
@@ -202,7 +206,7 @@ public boolean isVisible() {
202206
}
203207

204208
@Override
205-
public void setVisible(boolean visible) {
209+
public void setVisible(final boolean visible) {
206210
getStyle().set(DISPLAY, visible ? INLINE : "none");
207211
}
208212
}

src/main/resources/META-INF/frontend/simple-timer/simple-timer.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,27 +110,30 @@ Polymer({
110110
type: Boolean,
111111
value: false
112112
},
113+
targetId: {
114+
type: String,
115+
value: null,
116+
},
113117
/**
114118
* Time the timer has spent running since it was started
115119
*/
116-
_elapsedTime: {
120+
_elapsed: {
117121
type: Number,
118122
value: 0
119123
},
120124

121125
_formattedTime: {
122126
type: String,
123-
value: '0'
127+
value: '0',
128+
observer: "_updateTarget",
124129
}
125130
},
126131

127132
ready: function() {
128-
if (this.countUp) {
129-
this.set('currentTime', 0);
130-
} else {
131-
this.set('currentTime', this.startTime);
132-
}
133-
this.set('_formattedTime', this._formatTime(this.currentTime.toString()));
133+
if (this.currentTime===undefined) {
134+
this.set('currentTime', this.countUp ? 0 : this.startTime);
135+
}
136+
this.set('_formattedTime', this._formatTime(this.currentTime.toString()));
134137
},
135138

136139
start: function() {
@@ -199,5 +202,10 @@ Polymer({
199202
hours = hours.toString().padStart(2, '0');
200203
}
201204
return (this.hours ? hours + ':' : '') + (this.minutes || this.hours ? minutes + ':' : '') + seconds + (this.fractions ? ('.' + timeString[1].substring(0,2)) : '')
202-
}
205+
},
206+
_updateTarget: function(newValue, oldValue){
207+
if (document.getElementById(this.targetId)) {
208+
document.getElementById(this.targetId).innerText = newValue;
209+
}
210+
}
203211
});
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*-
2+
* #%L
3+
* Template Add-on
4+
* %%
5+
* Copyright (C) 2024 Flowing Code
6+
* %%
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* #L%
19+
*/
20+
21+
package com.flowingcode.addons.simpletimer.integration;
22+
23+
import com.vaadin.testbench.ScreenshotOnFailureRule;
24+
import com.vaadin.testbench.TestBench;
25+
import com.vaadin.testbench.parallel.ParallelTest;
26+
import io.github.bonigarcia.wdm.WebDriverManager;
27+
import org.junit.Before;
28+
import org.junit.BeforeClass;
29+
import org.junit.Rule;
30+
import org.openqa.selenium.chrome.ChromeDriver;
31+
32+
/**
33+
* Base class for ITs
34+
*
35+
* <p>The tests use Chrome driver (see pom.xml for integration-tests profile) to run integration
36+
* tests on a headless Chrome. If a property {@code test.use .hub} is set to true, {@code
37+
* AbstractViewTest} will assume that the TestBench test is running in a CI environment. In order to
38+
* keep the this class light, it makes certain assumptions about the CI environment (such as
39+
* available environment variables). It is not advisable to use this class as a base class for you
40+
* own TestBench tests.
41+
*
42+
* <p>To learn more about TestBench, visit <a
43+
* href="https://vaadin.com/docs/v10/testbench/testbench-overview.html">Vaadin TestBench</a>.
44+
*/
45+
public abstract class AbstractViewTest extends ParallelTest {
46+
private static final int SERVER_PORT = 8080;
47+
48+
private final String route;
49+
50+
@Rule public ScreenshotOnFailureRule rule = new ScreenshotOnFailureRule(this, true);
51+
52+
public AbstractViewTest() {
53+
this("");
54+
}
55+
56+
protected AbstractViewTest(String route) {
57+
this.route = route;
58+
}
59+
60+
@BeforeClass
61+
public static void setupClass() {
62+
WebDriverManager.chromedriver().setup();
63+
}
64+
65+
@Override
66+
@Before
67+
public void setup() throws Exception {
68+
if (isUsingHub()) {
69+
super.setup();
70+
} else {
71+
setDriver(TestBench.createDriver(new ChromeDriver()));
72+
}
73+
getDriver().get(getURL(route));
74+
}
75+
76+
/**
77+
* Returns deployment host name concatenated with route.
78+
*
79+
* @return URL to route
80+
*/
81+
private static String getURL(String route) {
82+
return String.format("http://%s:%d/%s", getDeploymentHostname(), SERVER_PORT, route);
83+
}
84+
85+
/** Property set to true when running on a test hub. */
86+
private static final String USE_HUB_PROPERTY = "test.use.hub";
87+
88+
/**
89+
* Returns whether we are using a test hub. This means that the starter is running tests in
90+
* Vaadin's CI environment, and uses TestBench to connect to the testing hub.
91+
*
92+
* @return whether we are using a test hub
93+
*/
94+
private static boolean isUsingHub() {
95+
return Boolean.TRUE.toString().equals(System.getProperty(USE_HUB_PROPERTY));
96+
}
97+
98+
/**
99+
* If running on CI, get the host name from environment variable HOSTNAME
100+
*
101+
* @return the host name
102+
*/
103+
private static String getDeploymentHostname() {
104+
return isUsingHub() ? System.getenv("HOSTNAME") : "localhost";
105+
}
106+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.flowingcode.addons.simpletimer.integration;
2+
3+
public interface IntegrationCallables {
4+
5+
void setStartTime(Integer startTime);
6+
7+
void setEndTime(Integer endTime);
8+
9+
void start();
10+
11+
void pause();
12+
13+
void reset();
14+
15+
boolean isRunning();
16+
17+
void openDialog();
18+
19+
void closeDialog();
20+
// BigDecimal getCurrentTime();
21+
//
22+
// CompletableFuture<BigDecimal> getCurrentTimeAsync();
23+
//
24+
// Registration addCurrentTimeChangeListener(PropertyChangeListener listener, long period,
25+
// TimeUnit periodUnit);
26+
//
27+
// Registration addTimerEndEvent(ComponentEventListener<TimerEndedEvent> listener);
28+
29+
}

0 commit comments

Comments
 (0)