From e24d2f2d3ef1003c835d055278365462246d8bb6 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Sun, 14 Dec 2025 19:24:05 +0100 Subject: [PATCH] WW-5444 Add HTML5 theme with comprehensive unit tests (#1422) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WW-5444 Defines new html5 theme * feat(themes): move html5 theme from showcase to core - Move 42 FreeMarker templates to core/src/main/resources/template/html5/ - Remove duplicate templates from showcase - Makes html5 theme available to all applications via struts2-core.jar - Enables unit testing in core module - Fix Html5Action import from XWork2 to Struts2 package - Add Apache license header to Html5Action Resolves WW-5444 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * docs: add implementation plan for html5 theme migration Add detailed implementation plan documenting the migration of html5 theme from showcase to core, including step-by-step instructions, verification procedures, and acceptance criteria. Related to WW-5444 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * test(html5-theme): add comprehensive unit tests and fix template variables - Add testGenericHtml5() methods to 13 UI tag test classes - Create theme.properties with parent=simple configuration - Migrate all 32 HTML5 templates from deprecated 'parameters' to 'attributes' variable - Exclude DoubleSelect and UpDownSelect (not supported in HTML5 theme) - All 26 HTML5 theme tests passing (100% success rate) Components tested: Textfield, Textarea, Password, Checkbox, CheckboxList, Radio, Select, File, Hidden, Label, ComboBox, Reset, Submit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * docs: update CLAUDE.md and remove jakarta-migration-helper agent - Update CLAUDE.md with current project guidelines - Update test-runner agent documentation - Remove deprecated jakarta-migration-helper agent 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * Adds missing header * test(html5-theme): complete unit test coverage for remaining 5 tag classes Add HTML5 theme tests to ActionErrorTagTest, ActionMessageTagTest, FieldErrorTagTest, AnchorTest, and FormTagTest. This completes Phase 1 of the HTML5 theme testing plan. Changes: - Add 24 new HTML5 theme unit tests across 5 test classes - Create 17 expected output files for HTML5 theme validation - Test coverage: action errors, action messages, field errors, anchors, and forms - All tests verify HTML5 clean markup without table-based layouts Coverage: 18 of 18 UI tag test classes now have HTML5 tests (100%) Tests passing: 24/24 HTML5 tests successful 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * test(html5-theme): add integration tests for showcase application - Create Html5TagExampleTest with 5 comprehensive integration tests - Add fielderror tag demonstration to html5/index.jsp - Validate HTML5 theme rendering, error display, and clean markup - All tests passing (5/5) with HtmlUnit and Jetty integration Tests validate: - Page load and HTTP status (200) - Action errors, messages, and field errors display - Clean semantic markup (ul lists, no table layouts) - Anchor tag rendering - Namespace isolation under /html5 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * feat(html5-theme): WW-5444 replace FreeMarker compress with Struts compress tag - Create CompressModel.java to enable <@s.compress> in FreeMarker templates - Register compress tag in StrutsModels.java for @s namespace access - Migrate all 29 HTML5 theme templates from <#compress> to <@s.compress> - Maintain identical compression behavior (uses same >\\s+< regex pattern) - All 153 HTML5 theme unit tests pass without modification This change leverages the new configurable Compress component (WW-5256) which provides devMode awareness and security protections while maintaining the same whitespace removal behavior as FreeMarker's built-in directive. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 * feat(html5-theme): WW-5444 simplifies tags templates and extends example --------- Co-authored-by: Claude --- CLAUDE.md | 3 +- .../struts2/showcase/action/Html5Action.java | 32 + apps/showcase/src/main/resources/struts.xml | 6 + .../main/webapp/WEB-INF/decorators/main.jsp | 69 +- .../src/main/webapp/WEB-INF/html5/index.jsp | 283 +++++++ .../src/main/webapp/WEB-INF/sitemesh3.xml | 1 + .../struts2/showcase/Html5TagExampleTest.java | 183 ++++ .../template/FreemarkerTemplateEngine.java | 1 + .../views/freemarker/tags/CompressModel.java | 39 + .../views/freemarker/tags/StrutsModels.java | 11 +- .../main/resources/template/html5/a-close.ftl | 48 ++ core/src/main/resources/template/html5/a.ftl | 20 + .../resources/template/html5/actionerror.ftl | 41 + .../template/html5/actionmessage.ftl | 41 + .../resources/template/html5/checkbox.ftl | 50 ++ .../resources/template/html5/checkboxlist.ftl | 117 +++ .../resources/template/html5/combobox.ftl | 101 +++ .../template/html5/common-attributes.ftl | 23 + .../template/html5/controlfooter.ftl | 20 + .../template/html5/controlheader.ftl | 20 + .../src/main/resources/template/html5/css.ftl | 33 + .../template/html5/datetextfield.ftl | 21 + .../main/resources/template/html5/debug.ftl | 92 +++ .../resources/template/html5/doubleselect.ftl | 21 + .../template/html5/dynamic-attributes.ftl | 43 + .../main/resources/template/html5/empty.ftl | 20 + .../resources/template/html5/fielderror.ftl | 80 ++ .../main/resources/template/html5/file.ftl | 47 ++ .../resources/template/html5/form-close.ftl | 22 + .../main/resources/template/html5/form.ftl | 68 ++ .../main/resources/template/html5/head.ftl | 21 + .../main/resources/template/html5/hidden.ftl | 41 + .../template/html5/inputtransferselect.ftl | 21 + .../main/resources/template/html5/label.ftl | 40 + .../main/resources/template/html5/link.ftl | 72 ++ .../main/resources/template/html5/nonce.ftl | 23 + .../resources/template/html5/optgroup.ftl | 69 ++ .../template/html5/optiontransferselect.ftl | 21 + .../resources/template/html5/password.ftl | 53 ++ .../html5/prefixed-dynamic-attributes.ftl | 37 + .../resources/template/html5/radiomap.ftl | 105 +++ .../main/resources/template/html5/reset.ftl | 85 ++ .../resources/template/html5/script-close.ftl | 21 + .../main/resources/template/html5/script.ftl | 52 ++ .../template/html5/scripting-events.ftl | 62 ++ .../main/resources/template/html5/select.ftl | 145 ++++ .../resources/template/html5/submit-close.ftl | 27 + .../main/resources/template/html5/submit.ftl | 92 +++ .../main/resources/template/html5/text.ftl | 54 ++ .../resources/template/html5/textarea.ftl | 63 ++ .../resources/template/html5/theme.properties | 19 + .../main/resources/template/html5/token.ftl | 22 + .../resources/template/html5/updownselect.ftl | 21 + .../views/jsp/ui/ActionErrorTagTest.java | 82 ++ .../views/jsp/ui/ActionMessageTagTest.java | 82 ++ .../struts2/views/jsp/ui/AnchorTest.java | 111 +++ .../views/jsp/ui/CheckboxListTest.java | 13 + .../struts2/views/jsp/ui/CheckboxTest.java | 11 + .../struts2/views/jsp/ui/ComboBoxTest.java | 13 + .../views/jsp/ui/FieldErrorTagTest.java | 99 +++ .../apache/struts2/views/jsp/ui/FileTest.java | 11 + .../struts2/views/jsp/ui/FormTagTest.java | 125 +++ .../struts2/views/jsp/ui/HiddenTest.java | 11 + .../struts2/views/jsp/ui/LabelTest.java | 11 + .../struts2/views/jsp/ui/PasswordTest.java | 11 + .../struts2/views/jsp/ui/RadioTest.java | 13 + .../struts2/views/jsp/ui/ResetTest.java | 11 + .../struts2/views/jsp/ui/SelectTest.java | 13 + .../struts2/views/jsp/ui/SubmitTest.java | 11 + .../struts2/views/jsp/ui/TextareaTest.java | 11 + .../struts2/views/jsp/ui/TextfieldTest.java | 11 + .../views/jsp/ui/Anchor-dynamic-html5.txt | 6 + .../struts2/views/jsp/ui/Formtag-1-html5.txt | 1 + .../views/jsp/ui/Formtag-dynamic-html5.txt | 1 + .../views/jsp/ui/Formtag-enctype-html5.txt | 1 + .../views/jsp/ui/Formtag-method-html5.txt | 1 + .../views/jsp/ui/Formtag-validate-html5.txt | 1 + .../views/jsp/ui/actionerror-1-html5.txt | 0 .../views/jsp/ui/actionerror-3-html5.txt | 1 + .../views/jsp/ui/actionmessage-1-html5.txt | 0 .../views/jsp/ui/actionmessage-3-html5.txt | 1 + .../views/jsp/ui/fielderror-2-html5.txt | 0 .../views/jsp/ui/fielderror-3-html5.txt | 1 + .../views/jsp/ui/fielderror-6-html5.txt | 1 + .../jsp/ui/fielderror-filtered-html5.txt | 1 + .../struts2/views/jsp/ui/href-1-html5.txt | 4 + .../struts2/views/jsp/ui/href-3-html5.txt | 1 + .../views/jsp/ui/href-disabled-html5.txt | 1 + ...-11-23-WW-5444-move-html5-theme-to-core.md | 398 +++++++++ .../2025-11-26-WW-5444-html5-missing-tests.md | 779 ++++++++++++++++++ .../2025-11-23-WW-5444-html5-theme-testing.md | 518 ++++++++++++ ...25-11-26-WW-5444-html5-theme-validation.md | 413 ++++++++++ 92 files changed, 5461 insertions(+), 41 deletions(-) create mode 100644 apps/showcase/src/main/java/org/apache/struts2/showcase/action/Html5Action.java create mode 100644 apps/showcase/src/main/webapp/WEB-INF/html5/index.jsp create mode 100644 apps/showcase/src/test/java/it/org/apache/struts2/showcase/Html5TagExampleTest.java create mode 100644 core/src/main/java/org/apache/struts2/views/freemarker/tags/CompressModel.java create mode 100644 core/src/main/resources/template/html5/a-close.ftl create mode 100644 core/src/main/resources/template/html5/a.ftl create mode 100644 core/src/main/resources/template/html5/actionerror.ftl create mode 100644 core/src/main/resources/template/html5/actionmessage.ftl create mode 100644 core/src/main/resources/template/html5/checkbox.ftl create mode 100644 core/src/main/resources/template/html5/checkboxlist.ftl create mode 100644 core/src/main/resources/template/html5/combobox.ftl create mode 100644 core/src/main/resources/template/html5/common-attributes.ftl create mode 100644 core/src/main/resources/template/html5/controlfooter.ftl create mode 100644 core/src/main/resources/template/html5/controlheader.ftl create mode 100644 core/src/main/resources/template/html5/css.ftl create mode 100644 core/src/main/resources/template/html5/datetextfield.ftl create mode 100644 core/src/main/resources/template/html5/debug.ftl create mode 100644 core/src/main/resources/template/html5/doubleselect.ftl create mode 100644 core/src/main/resources/template/html5/dynamic-attributes.ftl create mode 100644 core/src/main/resources/template/html5/empty.ftl create mode 100644 core/src/main/resources/template/html5/fielderror.ftl create mode 100644 core/src/main/resources/template/html5/file.ftl create mode 100644 core/src/main/resources/template/html5/form-close.ftl create mode 100644 core/src/main/resources/template/html5/form.ftl create mode 100644 core/src/main/resources/template/html5/head.ftl create mode 100644 core/src/main/resources/template/html5/hidden.ftl create mode 100644 core/src/main/resources/template/html5/inputtransferselect.ftl create mode 100644 core/src/main/resources/template/html5/label.ftl create mode 100644 core/src/main/resources/template/html5/link.ftl create mode 100644 core/src/main/resources/template/html5/nonce.ftl create mode 100644 core/src/main/resources/template/html5/optgroup.ftl create mode 100644 core/src/main/resources/template/html5/optiontransferselect.ftl create mode 100644 core/src/main/resources/template/html5/password.ftl create mode 100644 core/src/main/resources/template/html5/prefixed-dynamic-attributes.ftl create mode 100644 core/src/main/resources/template/html5/radiomap.ftl create mode 100644 core/src/main/resources/template/html5/reset.ftl create mode 100644 core/src/main/resources/template/html5/script-close.ftl create mode 100644 core/src/main/resources/template/html5/script.ftl create mode 100644 core/src/main/resources/template/html5/scripting-events.ftl create mode 100644 core/src/main/resources/template/html5/select.ftl create mode 100644 core/src/main/resources/template/html5/submit-close.ftl create mode 100644 core/src/main/resources/template/html5/submit.ftl create mode 100644 core/src/main/resources/template/html5/text.ftl create mode 100644 core/src/main/resources/template/html5/textarea.ftl create mode 100644 core/src/main/resources/template/html5/theme.properties create mode 100644 core/src/main/resources/template/html5/token.ftl create mode 100644 core/src/main/resources/template/html5/updownselect.ftl create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/Anchor-dynamic-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-1-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-dynamic-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-enctype-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-method-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-validate-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/actionerror-1-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/actionerror-3-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/actionmessage-1-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/actionmessage-3-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-2-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-3-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-6-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-filtered-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/href-1-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/href-3-html5.txt create mode 100644 core/src/test/resources/org/apache/struts2/views/jsp/ui/href-disabled-html5.txt create mode 100644 thoughts/shared/plans/2025-11-23-WW-5444-move-html5-theme-to-core.md create mode 100644 thoughts/shared/plans/2025-11-26-WW-5444-html5-missing-tests.md create mode 100644 thoughts/shared/research/2025-11-23-WW-5444-html5-theme-testing.md create mode 100644 thoughts/shared/validation/2025-11-26-WW-5444-html5-theme-validation.md diff --git a/CLAUDE.md b/CLAUDE.md index 5f338f789..a536f59d0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -165,10 +165,9 @@ When running tests, use this priority order: ### Specialized Agents - `security-analyzer` - OGNL injection scanning, CVE detection -- `test-runner` - Maven test execution and coverage analysis +- `test-runner` - Maven test execution and coverage analysis, use this agent to RUN the tests - `code-quality-checker` - JavaDoc compliance, pattern consistency - `config-validator` - struts.xml validation, interceptor analysis -- `jakarta-migration-helper` - Jakarta EE migration assistance - `codebase-analyzer` - Project structure and architecture analysis - `codebase-locator` - Code and file location assistance - `codebase-pattern-finder` - Pattern examples and usage diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/action/Html5Action.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/action/Html5Action.java new file mode 100644 index 000000000..a4e6b2d7d --- /dev/null +++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/action/Html5Action.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.struts2.showcase.action; + +import org.apache.struts2.ActionSupport; + +public class Html5Action extends ActionSupport { + + @Override + public String execute() throws Exception { + addActionError("Action error: only html5"); + addActionMessage("Action message: only html5"); + addFieldError("testField", "Field error: only html5"); + return super.execute(); + } +} diff --git a/apps/showcase/src/main/resources/struts.xml b/apps/showcase/src/main/resources/struts.xml index 1b57083b3..5c1cf37ff 100644 --- a/apps/showcase/src/main/resources/struts.xml +++ b/apps/showcase/src/main/resources/struts.xml @@ -160,6 +160,12 @@ + + + /WEB-INF/html5/index.jsp + + + diff --git a/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp b/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp index b2eeaca62..b0440732d 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp +++ b/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp @@ -132,54 +132,49 @@