From b05a2d84db7f4865df65bd8864e9eb18d128a1fe Mon Sep 17 00:00:00 2001 From: thomaswoehlke Date: Tue, 7 Apr 2020 09:44:19 +0200 Subject: [PATCH 1/5] Fixed #126 --- run.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/run.sh b/run.sh index 99ed1c96..5c5b3870 100755 --- a/run.sh +++ b/run.sh @@ -19,10 +19,14 @@ function setupHeroku() { heroku ps -a simpleworklist } -function buildLikeHeroku() { +function buildLikeHerokuWithSite() { ./mvnw -DskipTests clean dependency:list install site site:deploy } +function buildLikeHeroku() { + ./mvnw -DskipTests clean dependency:list install +} + function runHerokuLocal() { buildLikeHeroku heroku ps -a simpleworklist From f73734a88dc1902566287f4236167b2d1a96aec2 Mon Sep 17 00:00:00 2001 From: thomaswoehlke Date: Tue, 7 Apr 2020 09:45:44 +0200 Subject: [PATCH 2/5] Fixed #126 --- run.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/run.sh b/run.sh index 5c5b3870..408600d5 100755 --- a/run.sh +++ b/run.sh @@ -7,7 +7,7 @@ function runDev() { } function runTest() { - ./mvnw -B -DskipTests=false clean dependency:list install --file pom.xml + ./mvnw -B -DskipTests=false clean dependency:list install --file pom.xml } function runGithubTestBuild() { @@ -37,10 +37,10 @@ function runHerokuLocal() { function main() { #runGithubTestBuild #setupHeroku - buildLikeHeroku + #buildLikeHeroku #runHerokuLocal #runDev - #runTest + runTest } main From 1c97c62ad92511b1bcd42b428efc61d029c32243 Mon Sep 17 00:00:00 2001 From: thomaswoehlke Date: Tue, 7 Apr 2020 10:33:26 +0200 Subject: [PATCH 3/5] Fixed #126 --- etc/TODO.md | 2 + pom.xml | 4 + .../woehlke/simpleworklist/SmokeTests.java | 125 ++++++++++++++++-- 3 files changed, 123 insertions(+), 8 deletions(-) diff --git a/etc/TODO.md b/etc/TODO.md index 2572afc5..37048b1b 100644 --- a/etc/TODO.md +++ b/etc/TODO.md @@ -90,3 +90,5 @@ Fixed #122, Fixed #123, Fixed #127, Fixed #130, Fixed #152, Fixed #153, Fixed #1 Fixed #129 Fixed #126 + +https://developer.okta.com/blog/2019/03/28/test-java-spring-boot-junit5 diff --git a/pom.xml b/pom.xml index 70dae0e8..b17a2ab6 100644 --- a/pom.xml +++ b/pom.xml @@ -379,6 +379,10 @@ spring-boot-starter-test test + + junit + junit + org.junit.vintage junit-vintage-engine diff --git a/src/test/java/org/woehlke/simpleworklist/SmokeTests.java b/src/test/java/org/woehlke/simpleworklist/SmokeTests.java index 27791493..f6aa6c67 100644 --- a/src/test/java/org/woehlke/simpleworklist/SmokeTests.java +++ b/src/test/java/org/woehlke/simpleworklist/SmokeTests.java @@ -1,24 +1,24 @@ package org.woehlke.simpleworklist; import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.context.event.annotation.AfterTestClass; -import org.springframework.test.context.event.annotation.BeforeTestClass; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.context.WebApplicationContext; import org.woehlke.simpleworklist.config.UserAccountTestDataService; import java.net.URL; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; @Slf4j +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SmokeTests { @@ -38,158 +38,267 @@ public class SmokeTests { @Autowired private UserAccountTestDataService userAccountTestDataService; + + private final String eyecatcherH1 = "##################################################################"; + private final String eyecatcherH2 = "------------------------------------------------------------------"; + private final String eyecatcherH3 = "******************************************************************"; + @BeforeEach public void setUp() throws Exception { + log.info(eyecatcherH1); log.info(" @BeforeEach setUp()"); + log.info(eyecatcherH2); this.base = new URL("http://localhost:" + port + "/"); this.mockMvc = webAppContextSetup(wac).build(); - userAccountTestDataService.setUp(); + log.info(" Server URL: "+this.base.toString()); + //userAccountTestDataService.setUp(); + log.info(eyecatcherH1); } - @BeforeTestClass + @BeforeAll public void runBeforeTestClass() throws Exception { + log.info(eyecatcherH1); + log.info(" @BeforeTestClass runBeforeTestClass"); + log.info(eyecatcherH2); + this.base = new URL("http://localhost:" + port + "/"); + this.mockMvc = webAppContextSetup(wac).build(); + log.info(" Server URL: "+this.base.toString()); + log.info(eyecatcherH2); + userAccountTestDataService.setUp(); + log.info(eyecatcherH2); log.info(" @BeforeTestClass runBeforeTestClass"); + log.info(eyecatcherH1); } - @AfterTestClass + @AfterAll public void runAfterTestClass() { + log.info(eyecatcherH1); log.info(" @AfterTestClass clearContext"); + log.info(eyecatcherH2); SecurityContextHolder.clearContext(); + log.info(eyecatcherH1); } + + @DisplayName("Test Mock helloService + helloRepository") + @Order(1) @Test public void testF001ServerStarts(){ + log.info(eyecatcherH1); log.info("testF001ServerStarts"); + log.info(eyecatcherH2); + log.info("Server URL: "+this.base.toString()); + assertTrue(true); + log.info(eyecatcherH2); } + @Order(2) @Test public void testF002HomePageRendered(){ + log.info(eyecatcherH1); log.info("testF002HomePageRendered"); + log.info(eyecatcherH2); + log.info(eyecatcherH2); } + @Order(3) @Test public void testF003Registration(){ + log.info(eyecatcherH1); log.info("testF003Registration"); + log.info(eyecatcherH2); } + @Order(4) @Test public void testF004PasswordRecovery(){ + log.info(eyecatcherH1); log.info("testF004PasswordRecovery"); + log.info(eyecatcherH2); } + @Order(5) @Test public void testF005Login(){ + log.info(eyecatcherH1); log.info("testF005Login"); + log.info(eyecatcherH2); } + @Order(6) @Test public void testF006PageAfterFirstSuccessfulLogin(){ + log.info(eyecatcherH1); log.info("testF006PageAfterFirstSuccessfulLogins"); + log.info(eyecatcherH2); } + @Order(7) @Test public void testF007AddFirstNewTaskToInbox(){ + log.info(eyecatcherH1); log.info("testF007AddFirstNewTaskToInbox"); + log.info(eyecatcherH2); } + @Order(8) @Test public void testF008AddAnotherNewTaskToInbox(){ + log.info(eyecatcherH1); log.info("testF008AddAnotherNewTaskToInbox"); + log.info(eyecatcherH2); } + @Order(9) @Test public void testF009AddTaskToProjectRoot(){ + log.info(eyecatcherH1); log.info("testF009AddTaskToProjectRoot"); + log.info(eyecatcherH2); } + + @Order(10) @Test public void testF010AddSubProjectToProjectRoot(){ + log.info(eyecatcherH1); log.info("testF010AddSubProjectToProjectRoot"); + log.info(eyecatcherH2); } + @Order(11) @Test public void testF011SetFocusOfTask(){ + log.info(eyecatcherH1); log.info("testF011SetFocusOfTask"); + log.info(eyecatcherH2); } + @Order(12) @Test public void testF012UnSetFocusOfTask(){ + log.info(eyecatcherH1); log.info("testF012UnSetFocusOfTask"); + log.info(eyecatcherH2); } + @Order(13) @Test public void testF013ShowTaskstateInbox(){ + log.info(eyecatcherH1); log.info("testF013ShowTaskstateInbox"); + log.info(eyecatcherH2); } + @Order(14) @Test public void testF014ShowTaskstateToday(){ + log.info(eyecatcherH1); log.info("testF014ShowTaskstateToday"); + log.info(eyecatcherH2); } + @Order(15) @Test public void testF015ShowTaskstateNext(){ + log.info(eyecatcherH1); log.info("testF015ShowTaskstateNext"); + log.info(eyecatcherH2); } + @Order(16) @Test public void testF016ShowTaskstateWaiting(){ + log.info(eyecatcherH1); log.info("testF016ShowTaskstateWaiting"); + log.info(eyecatcherH2); } + @Order(17) @Test public void testF017ShowTaskstateScheduled(){ + log.info(eyecatcherH1); log.info("testF017ShowTaskstateScheduled"); + log.info(eyecatcherH2); } + @Order(18) @Test public void testF018ShowTaskstateSomeday(){ + log.info(eyecatcherH1); log.info("testF018ShowTaskstateSomeday"); + log.info(eyecatcherH2); } + @Order(19) @Test public void testF019ShowTaskstateFocus(){ + log.info(eyecatcherH1); log.info("testF019ShowTaskstateFocus"); + log.info(eyecatcherH2); } + @Order(20) @Test public void testF020ShowTaskstateCompleted(){ + log.info(eyecatcherH1); log.info("testF020ShowTaskstateCompleted"); + log.info(eyecatcherH2); } + @Order(21) @Test public void testF021ShowTaskstateTrash(){ + log.info(eyecatcherH1); log.info("testF021ShowTaskstateTrash"); + log.info(eyecatcherH2); } + @Order(22) @Test public void testF022TaskEdit(){ + log.info(eyecatcherH1); log.info("testF022TaskEdit"); + log.info(eyecatcherH2); } + @Order(23) @Test public void testF023TaskEditFormChangeTaskstateViaDropDown(){ + log.info(eyecatcherH1); log.info("testF023TaskEditFormChangeTaskstateViaDropDown"); + log.info(eyecatcherH2); } + @Order(24) @Test public void testF024TaskComplete(){ + log.info(eyecatcherH1); log.info("testF024TaskComplete"); + log.info(eyecatcherH2); } + @Order(25) @Test public void testF025TaskIncomplete(){ + log.info(eyecatcherH1); log.info("testF025TaskIncomplete"); + log.info(eyecatcherH2); } + @Order(26) @Test public void testF026TaskDelete(){ + log.info(eyecatcherH1); log.info("testF026TaskDelete"); + log.info(eyecatcherH2); } + @Order(27) @Test public void testF027TaskUndelete(){ + log.info(eyecatcherH1); log.info("testF027TaskUndelete"); + log.info(eyecatcherH2); } - } From 84de2d61cf84f63e24d6183f673e23127f7e448f Mon Sep 17 00:00:00 2001 From: thomaswoehlke Date: Tue, 7 Apr 2020 10:52:29 +0200 Subject: [PATCH 4/5] Fixed #126 --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index b17a2ab6..ffd7d508 100644 --- a/pom.xml +++ b/pom.xml @@ -865,6 +865,17 @@ + + org.apache.maven.plugins + maven-failsafe-plugin + + ${skipTests} + + default + ${skipTests} + + + From 9e245d9c5c0e7f31a21ea8cb3286d2f7e9185c7d Mon Sep 17 00:00:00 2001 From: thomaswoehlke Date: Tue, 7 Apr 2020 11:52:21 +0200 Subject: [PATCH 5/5] Fixed #126 --- .../woehlke/simpleworklist/SmokeTests.java | 60 +++++++++++++++---- .../config/FunctionalRequirements.java | 42 +++++++++++++ .../simpleworklist/config/Requirements.java | 34 +++++++++++ 3 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 src/test/java/org/woehlke/simpleworklist/config/FunctionalRequirements.java create mode 100644 src/test/java/org/woehlke/simpleworklist/config/Requirements.java diff --git a/src/test/java/org/woehlke/simpleworklist/SmokeTests.java b/src/test/java/org/woehlke/simpleworklist/SmokeTests.java index f6aa6c67..77a79a1b 100644 --- a/src/test/java/org/woehlke/simpleworklist/SmokeTests.java +++ b/src/test/java/org/woehlke/simpleworklist/SmokeTests.java @@ -3,37 +3,41 @@ import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.web.context.WebApplicationContext; +import org.woehlke.simpleworklist.config.FunctionalRequirements; import org.woehlke.simpleworklist.config.UserAccountTestDataService; import java.net.URL; +import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.woehlke.simpleworklist.config.Requirements.*; @Slf4j @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@AutoConfigureMockMvc +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class SmokeTests { @Autowired - ServletWebServerApplicationContext server; + private ServletWebServerApplicationContext server; @LocalServerPort - int port; + private int port; protected URL base; @Autowired - protected WebApplicationContext wac; - - protected MockMvc mockMvc; + private MockMvc mockMvc; @Autowired private UserAccountTestDataService userAccountTestDataService; @@ -49,7 +53,6 @@ public void setUp() throws Exception { log.info(" @BeforeEach setUp()"); log.info(eyecatcherH2); this.base = new URL("http://localhost:" + port + "/"); - this.mockMvc = webAppContextSetup(wac).build(); log.info(" Server URL: "+this.base.toString()); //userAccountTestDataService.setUp(); log.info(eyecatcherH1); @@ -61,7 +64,6 @@ public void runBeforeTestClass() throws Exception { log.info(" @BeforeTestClass runBeforeTestClass"); log.info(eyecatcherH2); this.base = new URL("http://localhost:" + port + "/"); - this.mockMvc = webAppContextSetup(wac).build(); log.info(" Server URL: "+this.base.toString()); log.info(eyecatcherH2); userAccountTestDataService.setUp(); @@ -80,7 +82,7 @@ public void runAfterTestClass() { } - @DisplayName("Test Mock helloService + helloRepository") + @DisplayName(F001) @Order(1) @Test public void testF001ServerStarts(){ @@ -92,15 +94,25 @@ public void testF001ServerStarts(){ log.info(eyecatcherH2); } + @DisplayName(F002) @Order(2) @Test - public void testF002HomePageRendered(){ + public void testF002HomePageRendered() throws Exception { log.info(eyecatcherH1); log.info("testF002HomePageRendered"); log.info(eyecatcherH2); + this.mockMvc.perform(get( this.base.toString() )) + .andDo(print()) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrl(this.base+"user/login")); + this.mockMvc.perform(get( this.base+"user/login" )) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("SimpleWorklist"))); log.info(eyecatcherH2); } + @DisplayName(F003) @Order(3) @Test public void testF003Registration(){ @@ -109,6 +121,7 @@ public void testF003Registration(){ log.info(eyecatcherH2); } + @DisplayName(F004) @Order(4) @Test public void testF004PasswordRecovery(){ @@ -117,6 +130,7 @@ public void testF004PasswordRecovery(){ log.info(eyecatcherH2); } + @DisplayName(F005) @Order(5) @Test public void testF005Login(){ @@ -125,6 +139,7 @@ public void testF005Login(){ log.info(eyecatcherH2); } + @DisplayName(F006) @Order(6) @Test public void testF006PageAfterFirstSuccessfulLogin(){ @@ -133,6 +148,7 @@ public void testF006PageAfterFirstSuccessfulLogin(){ log.info(eyecatcherH2); } + @DisplayName(F007) @Order(7) @Test public void testF007AddFirstNewTaskToInbox(){ @@ -141,6 +157,7 @@ public void testF007AddFirstNewTaskToInbox(){ log.info(eyecatcherH2); } + @DisplayName(F008) @Order(8) @Test public void testF008AddAnotherNewTaskToInbox(){ @@ -149,6 +166,7 @@ public void testF008AddAnotherNewTaskToInbox(){ log.info(eyecatcherH2); } + @DisplayName(F009) @Order(9) @Test public void testF009AddTaskToProjectRoot(){ @@ -157,6 +175,7 @@ public void testF009AddTaskToProjectRoot(){ log.info(eyecatcherH2); } + @DisplayName(F010) @Order(10) @Test public void testF010AddSubProjectToProjectRoot(){ @@ -165,6 +184,7 @@ public void testF010AddSubProjectToProjectRoot(){ log.info(eyecatcherH2); } + @DisplayName(F011) @Order(11) @Test public void testF011SetFocusOfTask(){ @@ -173,6 +193,7 @@ public void testF011SetFocusOfTask(){ log.info(eyecatcherH2); } + @DisplayName(F012) @Order(12) @Test public void testF012UnSetFocusOfTask(){ @@ -181,6 +202,7 @@ public void testF012UnSetFocusOfTask(){ log.info(eyecatcherH2); } + @DisplayName(F013) @Order(13) @Test public void testF013ShowTaskstateInbox(){ @@ -189,6 +211,7 @@ public void testF013ShowTaskstateInbox(){ log.info(eyecatcherH2); } + @DisplayName(F014) @Order(14) @Test public void testF014ShowTaskstateToday(){ @@ -197,6 +220,7 @@ public void testF014ShowTaskstateToday(){ log.info(eyecatcherH2); } + @DisplayName(F015) @Order(15) @Test public void testF015ShowTaskstateNext(){ @@ -205,6 +229,7 @@ public void testF015ShowTaskstateNext(){ log.info(eyecatcherH2); } + @DisplayName(F016) @Order(16) @Test public void testF016ShowTaskstateWaiting(){ @@ -213,6 +238,7 @@ public void testF016ShowTaskstateWaiting(){ log.info(eyecatcherH2); } + @DisplayName(F017) @Order(17) @Test public void testF017ShowTaskstateScheduled(){ @@ -221,6 +247,7 @@ public void testF017ShowTaskstateScheduled(){ log.info(eyecatcherH2); } + @DisplayName(F018) @Order(18) @Test public void testF018ShowTaskstateSomeday(){ @@ -229,6 +256,7 @@ public void testF018ShowTaskstateSomeday(){ log.info(eyecatcherH2); } + @DisplayName(F019) @Order(19) @Test public void testF019ShowTaskstateFocus(){ @@ -237,6 +265,7 @@ public void testF019ShowTaskstateFocus(){ log.info(eyecatcherH2); } + @DisplayName(F020) @Order(20) @Test public void testF020ShowTaskstateCompleted(){ @@ -245,6 +274,7 @@ public void testF020ShowTaskstateCompleted(){ log.info(eyecatcherH2); } + @DisplayName(F021) @Order(21) @Test public void testF021ShowTaskstateTrash(){ @@ -253,6 +283,7 @@ public void testF021ShowTaskstateTrash(){ log.info(eyecatcherH2); } + @DisplayName(F022) @Order(22) @Test public void testF022TaskEdit(){ @@ -261,6 +292,7 @@ public void testF022TaskEdit(){ log.info(eyecatcherH2); } + @DisplayName(F023) @Order(23) @Test public void testF023TaskEditFormChangeTaskstateViaDropDown(){ @@ -269,6 +301,7 @@ public void testF023TaskEditFormChangeTaskstateViaDropDown(){ log.info(eyecatcherH2); } + @DisplayName(F024) @Order(24) @Test public void testF024TaskComplete(){ @@ -277,6 +310,7 @@ public void testF024TaskComplete(){ log.info(eyecatcherH2); } + @DisplayName(F025) @Order(25) @Test public void testF025TaskIncomplete(){ @@ -285,6 +319,7 @@ public void testF025TaskIncomplete(){ log.info(eyecatcherH2); } + @DisplayName(F026) @Order(26) @Test public void testF026TaskDelete(){ @@ -293,6 +328,7 @@ public void testF026TaskDelete(){ log.info(eyecatcherH2); } + @DisplayName(F027) @Order(27) @Test public void testF027TaskUndelete(){ diff --git a/src/test/java/org/woehlke/simpleworklist/config/FunctionalRequirements.java b/src/test/java/org/woehlke/simpleworklist/config/FunctionalRequirements.java new file mode 100644 index 00000000..2678a0d3 --- /dev/null +++ b/src/test/java/org/woehlke/simpleworklist/config/FunctionalRequirements.java @@ -0,0 +1,42 @@ +package org.woehlke.simpleworklist.config; + +public enum FunctionalRequirements { + + F001("Server Starts"), + F002("Home Page rendered"), + F003("Registration"), + F004("Password Recovery"), + F005("Login"), + F006("Page after first successful Login"), + F007("Add first new Task to Inbox"), + F008("Add another new Task to Inbox"), + F009("Add Task to ProjectRoot"), + F010("Add SubProject to ProjectRoot"), + F011("setFocus of a Task"), + F012("unSetFocus of a Task"), + F013("show /taskstate/inbox"), + F014("show /taskstate/today"), + F015("show /taskstate/next"), + F016("show /taskstate/waiting"), + F017("show /taskstate/scheduled"), + F018("show /taskstate/someday"), + F019("show /taskstate/focus"), + F020("show /taskstate/completed"), + F021("show /taskstate/trash"), + F022("Task Edit"), + F023("Task Edit Form -> change Taskstate via DropDown"), + F024("Task complete"), + F025("Task incomplete"), + F026("Task delete"), + F027("Task undelete"); + + private String name; + + public String getName(){ + return name; + } + + FunctionalRequirements(String name){ + this.name = name; + } +} diff --git a/src/test/java/org/woehlke/simpleworklist/config/Requirements.java b/src/test/java/org/woehlke/simpleworklist/config/Requirements.java new file mode 100644 index 00000000..a937490b --- /dev/null +++ b/src/test/java/org/woehlke/simpleworklist/config/Requirements.java @@ -0,0 +1,34 @@ +package org.woehlke.simpleworklist.config; + +public interface Requirements { + +String Functional_Requirements = "Functional Requirements"; + + String F001 = "F001 Server Starts"; + String F002 = "F002 Home Page rendered"; + String F003 = "F003 Registration"; + String F004 = "F004 Password Recovery"; + String F005 = "F005 Login"; + String F006 = "F006 Page after first successful Login"; + String F007 = "F007 Add first new Task to Inbox"; + String F008 = "F008 Add another new Task to Inbox"; + String F009 = "F009 Add Task to ProjectRoot"; + String F010 = "F010 Add SubProject to ProjectRoot"; + String F011 = "F011 setFocus of a Task"; + String F012 = "F012 unSetFocus of a Task"; + String F013 = "F013 show /taskstate/inbox"; + String F014 = "F014 show /taskstate/today"; + String F015 = "F015 show /taskstate/next"; + String F016 = "F016 show /taskstate/waiting"; + String F017 = "F017 show /taskstate/scheduled"; + String F018 = "F018 show /taskstate/someday"; + String F019 = "F019 show /taskstate/focus"; + String F020 = "F020 show /taskstate/completed"; + String F021 = "F021 show /taskstate/trash"; + String F022 = "F022 Task Edit"; + String F023 = "F023 Task Edit Form -> change Taskstate via DropDown"; + String F024 = "F024 Task complete"; + String F025 = "F025 Task incomplete"; + String F026 = "F026 Task delete"; + String F027 = "F027 Task undelete"; +}