From ecbbf04cd13f31738133b9b08788c01a1124bfe3 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Mon, 16 Mar 2026 12:40:13 -0300 Subject: [PATCH 1/7] refactor: add LoginOverlayUtils utility class with helper methods Extract JavaScript DOM traversal into LoginOverlayUtils helper methods. Update LoginLayout and ReplaceableLoginOverlay to use these methods, and add removeForgotPassword() extracted from replaceForgotPassword(). Co-Authored-By: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> --- .../addons/extendedlogin/LoginLayout.java | 17 ++-- .../extendedlogin/LoginOverlayUtils.java | 88 ++++++++++++++++++ .../ReplaceableLoginOverlay.java | 89 +++++++++++++++---- 3 files changed, 170 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java diff --git a/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayout.java b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayout.java index 877c012..87e8730 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayout.java +++ b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayout.java @@ -51,14 +51,17 @@ public void removeRouterLayoutContent(HasElement oldContent) { protected void onAttach(AttachEvent attachEvent) { super.onAttach(attachEvent); setOpened(true); - this.getElement() - .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].replaceChildren())"); + this.getElement().executeJs( + LoginOverlayUtils.getLoginFormWrapperScript( + """ + formWrapper.querySelectorAll('[slot="form"], [slot="submit"], [slot="forgot-password"]').forEach(c => c.remove()); + """)); this.getElement().appendChild(content.getElement()); content.getElement().setAttribute("slot", "form"); - this.content - .getElement() - .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].appendChild(this))"); + this.content.getElement().executeJs( + LoginOverlayUtils.getLoginFormWrapperScript( + """ + formWrapper.appendChild(this); + """)); } } diff --git a/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java new file mode 100644 index 0000000..7983a75 --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java @@ -0,0 +1,88 @@ +/*- + * #%L + * Extended Login Add-on + * %% + * Copyright (C) 2023 - 2026 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.extendedlogin; + +/** + * Utility class for LoginOverlay. + */ +class LoginOverlayUtils { + + private LoginOverlayUtils() { + // Utility class + } + + /** + * Generates a JavaScript snippet that finds the overlay wrapper element. + * + * @param action the JavaScript code to execute on the overlay wrapper + * @return the complete JavaScript string with the overlay wrapper lookup and + * the provided action + */ + static String getOverlayWrapperScript(String action) { + return """ + setTimeout(() => { + var overlayWrapper = document.getElementById('vaadinLoginOverlayWrapper'); + if (!overlayWrapper) return; + %s + }); + """.formatted(action); + } + + /** + * Generates a JavaScript snippet that finds the form element. + * + * @param action the JavaScript code to execute on the form + * @return the complete JavaScript string with the form lookup and the provided + * action + */ + static String getFormWrapperScript(String action) { + return """ + setTimeout(() => { + var overlayFormWrapper = document.getElementById('vaadinLoginOverlayWrapper'); + if (!overlayFormWrapper) return; + var form = overlayFormWrapper.querySelector('form'); + if (form) { + %s + } + }); + """.formatted(action); + } + + /** + * Generates a JavaScript snippet that finds the form wrapper containing form + * elements. + * + * @param action the JavaScript code to execute on the form wrapper + * @return the complete JavaScript string with the form wrapper lookup and the + * provided action + */ + static String getLoginFormWrapperScript(String action) { + return """ + setTimeout(() => { + var overlayWrapper = document.getElementById('vaadinLoginOverlayWrapper'); + if (!overlayWrapper) return; + var formWrapper = overlayWrapper.querySelector('vaadin-login-form-wrapper'); + if (!formWrapper) return; + %s + }); + """.formatted(action); + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java index dcc1a68..0792f2a 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java +++ b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java @@ -28,49 +28,104 @@ */ public interface ReplaceableLoginOverlay extends HasElement { + /** + * Replaces the contents of the login form with the provided elements. Clears + * existing form + * contents and appends the provided elements. + * + * @param withElement the elements to add to the form + */ default void replaceFormComponents(HasElement... withElement) { - this.getElement() - .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].getElementsByTagName('form')[0].replaceChildren())"); + this.getElement().executeJs(LoginOverlayUtils.getFormWrapperScript("form.replaceChildren();")); + for (HasElement we : withElement) { getElement().appendChild(we.getElement()); this.getElement() - .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].getElementsByTagName('form')[0].appendChild($0))", - we.getElement()); + .executeJs(LoginOverlayUtils.getFormWrapperScript("form.appendChild($0);"), we.getElement()); } } + /** + * Replaces the header/brand component of the login overlay. Clears the brand + * section and appends + * the provided element. + * + * @param withElement the element to set as the new brand/header + */ default void replaceHeaderComponent(HasElement withElement) { getElement().appendChild(withElement.getElement()); + this.getElement() .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').shadowRoot.querySelector('[part=\"brand\"]').replaceChildren())"); + LoginOverlayUtils.getOverlayWrapperScript( + """ + var brand = overlayWrapper.shadowRoot ? overlayWrapper.shadowRoot.querySelector('[part="brand"]') : overlayWrapper.querySelector('[part="brand"]'); + if (brand) { + brand.replaceChildren(); + } + """)); + this.getElement() .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').shadowRoot.querySelector('[part=\"brand\"]').appendChild($0))", + LoginOverlayUtils.getOverlayWrapperScript( + """ + var brand = overlayWrapper.shadowRoot ? overlayWrapper.shadowRoot.querySelector('[part="brand"]') : overlayWrapper.querySelector('[part="brand"]'); + if (brand) { + brand.appendChild($0); + } + """), withElement); } + /** + * Removes the forgot password link from the login form. + */ + default void removeForgotPassword() { + this.getElement() + .executeJs( + LoginOverlayUtils.getLoginFormWrapperScript( + """ + var forgotPassword = formWrapper.querySelector('[slot="forgot-password"]'); + if (forgotPassword) { + forgotPassword.remove(); + } + """)); + } + + /** + * Replaces the forgot password component in the login overlay. Clears the + * forgot password section + * and appends the provided element. + * + * @param withElement the element to set as the new forgot password component + * + */ default void replaceForgotPassword(HasElement withElement) { withElement.getElement().setAttribute("slot", "forgot-password"); getElement().appendChild(withElement.getElement()); + this.removeForgotPassword(); this.getElement() .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].querySelector('[slot=\\\"forgot-password\\\"]').remove())"); - this.getElement() - .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].appendChild($0))", + LoginOverlayUtils.getLoginFormWrapperScript( + """ + formWrapper.appendChild($0); + """), withElement); } /** - * Removes the default submit button. + * Removes the default submit button. */ default void removeSubmitButton() { - this.getElement() - .executeJs( - "setTimeout(()=>document.getElementById('vaadinLoginOverlayWrapper').getElementsByTagName('vaadin-login-form-wrapper')[0].querySelector('[slot=\"submit\"]').remove())"); + this.getElement() + .executeJs( + LoginOverlayUtils.getLoginFormWrapperScript( + """ + var submitButton = formWrapper.querySelector('[slot="submit"]'); + if (submitButton) { + submitButton.remove(); + } + """)); } - + } From 9d0a401813cd192f3d2d5d53186ebf78a7d4853b Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Mon, 16 Mar 2026 12:45:06 -0300 Subject: [PATCH 2/7] feat: update DOM traversal to support Vaadin 24 and Vaadin 25 Add Vaadin 25 fallback logic to all LoginOverlayUtils helper methods. When getElementById('vaadinLoginOverlayWrapper') returns null (Vaadin 25), fall back to querying the vaadin-login-overlay shadow DOM for the wrapper. Close #23 Co-Authored-By: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> --- .../extendedlogin/LoginOverlayUtils.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java index 7983a75..757559a 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java +++ b/src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java @@ -30,6 +30,7 @@ private LoginOverlayUtils() { /** * Generates a JavaScript snippet that finds the overlay wrapper element. + * Handles both Vaadin 24 and Vaadin 25+ compatibility. * * @param action the JavaScript code to execute on the overlay wrapper * @return the complete JavaScript string with the overlay wrapper lookup and @@ -39,6 +40,13 @@ static String getOverlayWrapperScript(String action) { return """ setTimeout(() => { var overlayWrapper = document.getElementById('vaadinLoginOverlayWrapper'); + if (!overlayWrapper) { + var loginOverlay = document.querySelector('vaadin-login-overlay'); + if (loginOverlay && loginOverlay.shadowRoot) { + overlayWrapper = loginOverlay.shadowRoot + .querySelector('vaadin-login-overlay-wrapper'); + } + } if (!overlayWrapper) return; %s }); @@ -46,7 +54,8 @@ static String getOverlayWrapperScript(String action) { } /** - * Generates a JavaScript snippet that finds the form element. + * Generates a JavaScript snippet that finds the form element. Handles both + * Vaadin 24 and Vaadin 25+ compatibility. * * @param action the JavaScript code to execute on the form * @return the complete JavaScript string with the form lookup and the provided @@ -56,6 +65,9 @@ static String getFormWrapperScript(String action) { return """ setTimeout(() => { var overlayFormWrapper = document.getElementById('vaadinLoginOverlayWrapper'); + if (!overlayFormWrapper) { + overlayFormWrapper = document.querySelector('vaadin-login-overlay'); + } if (!overlayFormWrapper) return; var form = overlayFormWrapper.querySelector('form'); if (form) { @@ -67,7 +79,7 @@ static String getFormWrapperScript(String action) { /** * Generates a JavaScript snippet that finds the form wrapper containing form - * elements. + * elements. Handles both Vaadin 24 and Vaadin 25+ compatibility. * * @param action the JavaScript code to execute on the form wrapper * @return the complete JavaScript string with the form wrapper lookup and the @@ -77,6 +89,13 @@ static String getLoginFormWrapperScript(String action) { return """ setTimeout(() => { var overlayWrapper = document.getElementById('vaadinLoginOverlayWrapper'); + if (!overlayWrapper) { + var loginOverlay = document.querySelector('vaadin-login-overlay'); + if (loginOverlay && loginOverlay.shadowRoot) { + overlayWrapper = loginOverlay.shadowRoot + .querySelector('vaadin-login-overlay-wrapper'); + } + } if (!overlayWrapper) return; var formWrapper = overlayWrapper.querySelector('vaadin-login-form-wrapper'); if (!formWrapper) return; From 838185835704b4b3f76c2d985d7bb0bfff8fca05 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 5 Mar 2026 14:09:43 -0300 Subject: [PATCH 3/7] feat(demo): add AppShellConfiguratorImpl class --- pom.xml | 3 +- .../addons/AppShellConfiguratorImpl.java | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java diff --git a/pom.xml b/pom.xml index 0f6d858..6d24774 100644 --- a/pom.xml +++ b/pom.xml @@ -445,7 +445,8 @@ **/test/* **/it/* **/DemoView.class - **/DemoLayout.class + **/DemoLayout.class + **/AppShellConfiguratorImpl.class diff --git a/src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java b/src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java new file mode 100644 index 0000000..343396f --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java @@ -0,0 +1,28 @@ +/*- + * #%L + * Extended Login Add-on + * %% + * Copyright (C) 2023 - 2026 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons; + +import com.vaadin.flow.component.page.AppShellConfigurator; +import com.vaadin.flow.theme.Theme; + +@Theme +public class AppShellConfiguratorImpl implements AppShellConfigurator { + +} From 29ac2b63a26050da08a58f3d8e1740df39a0c5cd Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 5 Mar 2026 14:35:25 -0300 Subject: [PATCH 4/7] refactor(demo): use separate stylesheets for Vaadin 25 compatibility Use demo source condition attribute to select between Vaadin 24 & Vaadin 25 styles. --- .../ExtendedLoginOverlayDemo.java | 6 +++ .../addons/extendedlogin/LoginLayoutDemo.java | 6 +++ .../TestExtendedLoginOverlayView.java | 6 ++- .../extendedlogin/TestLoginLayoutView.java | 6 ++- .../styles/extended-login-styles-v25.css | 40 +++++++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/ExtendedLoginOverlayDemo.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/ExtendedLoginOverlayDemo.java index 2834456..d5de65b 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/ExtendedLoginOverlayDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/ExtendedLoginOverlayDemo.java @@ -29,6 +29,12 @@ @DemoSource( "/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java") +//#if vaadin eq 0 +@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles.css", + caption = "extended-login-styles.css", condition = "vaadin eq 24") +@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css", + caption = "extended-login-styles-v25.css", condition = "vaadin ge 25") +//#endif @PageTitle("Extended Login Overlay Demo") @SuppressWarnings("serial") @Route(value = "extended-login/login-overlay-demo", layout = ExtendedLoginDemoView.class) diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayoutDemo.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayoutDemo.java index af78c16..0b90fc0 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayoutDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayoutDemo.java @@ -29,6 +29,12 @@ @DemoSource("/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java") @DemoSource("/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java") +//#if vaadin eq 0 +@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles.css", + caption = "extended-login-styles.css", condition = "vaadin eq 24") +@DemoSource(value = "/src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css", + caption = "extended-login-styles-v25.css", condition = "vaadin ge 25") +//#endif @PageTitle("Login Layout Demo") @SuppressWarnings("serial") @Route(value = "extended-login/login-layout-demo", layout = ExtendedLoginDemoView.class) diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java index 7b69eb3..5bd43de 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java @@ -39,7 +39,11 @@ */ @SuppressWarnings("serial") @Route(value = "extended-login/login-overlay") -@CssImport("./styles/extended-login-styles.css") // hide-source +//#if vaadin eq 24 +@CssImport("./styles/extended-login-styles.css") +//#else +@CssImport("./styles/extended-login-styles-v25.css") +//#endif @Ignore public class TestExtendedLoginOverlayView extends Div { diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java index 180f3de..7938235 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java @@ -38,7 +38,11 @@ @SuppressWarnings("serial") @Route(value = "extended-login/login-layout", layout = TestLoginLayout.class) @Ignore -@CssImport("./styles/extended-login-styles.css") // hide-source +//#if vaadin eq 24 +@CssImport("./styles/extended-login-styles.css") +//#else +@CssImport("./styles/extended-login-styles-v25.css") +//#endif // show-source @Route("value = "extended-login/login-layout-demo", layout = TestLoginLayout.class) public class TestLoginLayoutView extends Div { diff --git a/src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css b/src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css new file mode 100644 index 0000000..8182882 --- /dev/null +++ b/src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css @@ -0,0 +1,40 @@ +/*- + * #%L + * Extended Login Add-on + * %% + * Copyright (C) 2023 - 2026 Flowing Code + * %% + * 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. + * #L% + */ +/*Demo styles*/ +vaadin-login-overlay::part(brand) { + background: black; + justify-content: center; + align-content: center; + flex-wrap: wrap; +} + +@media only screen and (max-height: 600px) and (min-width: 600px) and (orientation: landscape) { + vaadin-login-overlay::part(form) { + overflow: initial; + } +} + +vaadin-login-overlay::part(content) { + transform: scale(0.75); +} + +.wrap-iframe { + overflow: hidden; +} \ No newline at end of file From ec9044f49071498dfa6c4435e526f576c3e0515b Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 5 Mar 2026 16:09:13 -0300 Subject: [PATCH 5/7] feat(demo): add simple change password validation --- .../extendedlogin/TestLoginLayoutView.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java index 7938235..a07d5ee 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java @@ -46,6 +46,9 @@ // show-source @Route("value = "extended-login/login-layout-demo", layout = TestLoginLayout.class) public class TestLoginLayoutView extends Div { + private PasswordField password; + private PasswordField confirmPassword; + public TestLoginLayoutView() { add(createChangePasswordForm()); } @@ -53,9 +56,9 @@ public TestLoginLayoutView() { private FormLayout createChangePasswordForm() { TextField username = new TextField("Username"); username.setEnabled(false); - PasswordField password = new PasswordField("Password"); - PasswordField confirmPassword = new PasswordField("Confirm password"); - Button accept = new Button("Accept", ev -> Notification.show("Password changed.")); + password = new PasswordField("Password"); + confirmPassword = new PasswordField("Confirm password"); + Button accept = new Button("Accept", ev -> onAccept()); FormLayout formLayout = new FormLayout(); formLayout.add(username, password, confirmPassword, accept); @@ -69,4 +72,14 @@ private FormLayout createChangePasswordForm() { formLayout.setColspan(accept, 2); return formLayout; } + + private void onAccept() { + String passwordValue = this.password.getValue(); + String confirmPasswordValue = this.confirmPassword.getValue(); + if (passwordValue != null && !passwordValue.isBlank() && passwordValue.equals(confirmPasswordValue)) { + Notification.show("Password changed."); + } else { + Notification.show("Passwords do not match."); + } + } } From f97aba90d57ba1142adad977b7a86071e5ae816f Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Fri, 6 Mar 2026 15:50:46 -0300 Subject: [PATCH 6/7] test: refactor tests to make them compatible with Vaadin 24 & 25 Add testbench-rpc dependency to be able to retrieve Vaadin version. --- pom.xml | 6 +++ .../TestExtendedLoginOverlayView.java | 1 + .../addons/extendedlogin/TestLoginLayout.java | 1 + .../extendedlogin/it/AbstractViewTest.java | 8 +++- .../it/ExtendedLoginOverlayIT.java | 16 ++++++-- .../extendedlogin/it/LoginLayoutIT.java | 35 ++++++++++++----- .../it/ServerVersionCallables.java | 31 +++++++++++++++ ...stExtendedLoginOverlayIntegrationView.java | 38 +++++++++++++++++++ .../it/TestLoginLayoutIntegration.java | 37 ++++++++++++++++++ .../it/TestLoginLayoutIntegrationView.java | 32 ++++++++++++++++ 10 files changed, 189 insertions(+), 16 deletions(-) create mode 100644 src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java create mode 100644 src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestExtendedLoginOverlayIntegrationView.java create mode 100644 src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegration.java create mode 100644 src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegrationView.java diff --git a/pom.xml b/pom.xml index 6d24774..ac5538d 100644 --- a/pom.xml +++ b/pom.xml @@ -123,6 +123,12 @@ vaadin-testbench test + + com.flowingcode.vaadin.test + testbench-rpc + 1.5.0 + test + com.flowingcode.vaadin.addons.demo commons-demo diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java index 5bd43de..346ca16 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java @@ -64,4 +64,5 @@ public TestExtendedLoginOverlayView() { elo.setOpened(true); add(elo); } + } diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java index a399ef9..9761aeb 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java @@ -55,4 +55,5 @@ private LoginI18n createI18N() { i18n.setAdditionalInformation("Change your password"); return i18n; } + } diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java index 6e484bb..95a0f54 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java @@ -20,6 +20,7 @@ package com.flowingcode.vaadin.addons.extendedlogin.it; +import com.flowingcode.vaadin.testbench.rpc.HasRpcSupport; import com.vaadin.testbench.ScreenshotOnFailureRule; import com.vaadin.testbench.TestBench; import com.vaadin.testbench.parallel.ParallelTest; @@ -42,13 +43,15 @@ *

To learn more about TestBench, visit Vaadin TestBench. */ -public abstract class AbstractViewTest extends ParallelTest { +public abstract class AbstractViewTest extends ParallelTest implements HasRpcSupport { private static final int SERVER_PORT = 8080; private final String route; @Rule public ScreenshotOnFailureRule rule = new ScreenshotOnFailureRule(this, true); + ServerVersionCallables $server = createCallableProxy(ServerVersionCallables.class); + public AbstractViewTest() { this(""); } @@ -70,7 +73,8 @@ public void setup() throws Exception { } else { setDriver(TestBench.createDriver(new ChromeDriver())); } - getDriver().get(getURL(route)); + getDriver().get(getURL(route)); + getCommandExecutor().waitForVaadin(); } /** diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java index 4a8d24d..640c406 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java @@ -26,16 +26,21 @@ import com.vaadin.flow.component.button.testbench.ButtonElement; import com.vaadin.flow.component.combobox.testbench.ComboBoxElement; import com.vaadin.flow.component.html.testbench.AnchorElement; +import com.vaadin.flow.component.login.testbench.LoginOverlayElement; +import com.vaadin.testbench.ElementQuery; + import org.junit.Test; public class ExtendedLoginOverlayIT extends AbstractViewTest { public ExtendedLoginOverlayIT() { - super("extended-login/login-overlay"); + super("it/extended-login/login-overlay"); } @Test - public void testBasicBehaviour() { + public void testBasicBehaviour() { + boolean vaadin25 = $server.getMajorVersion() >= 25; + boolean comboBoxExists = $(ComboBoxElement.class).exists(); assertTrue("ComboBox not present", comboBoxExists); boolean buttonExists = $(ButtonElement.class).exists(); @@ -43,10 +48,13 @@ public void testBasicBehaviour() { if (buttonExists) { assertEquals("Sign In", $(ButtonElement.class).first().getText()); } - boolean anchorExists = $(AnchorElement.class).exists(); + + ElementQuery anchorQuery = vaadin25 ? $(LoginOverlayElement.class).first().$(AnchorElement.class) + : $(AnchorElement.class); + boolean anchorExists = anchorQuery.exists(); assertTrue("Anchor not present", anchorExists); if (anchorExists) { - assertEquals("Flowing Code Site", $(AnchorElement.class).first().getText()); + assertEquals("Flowing Code Site", anchorQuery.first().getText()); } } } diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/LoginLayoutIT.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/LoginLayoutIT.java index ba550e1..76a1244 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/LoginLayoutIT.java +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/LoginLayoutIT.java @@ -28,31 +28,46 @@ import com.vaadin.flow.component.html.testbench.H2Element; import com.vaadin.flow.component.html.testbench.ImageElement; import org.junit.Test; +import com.vaadin.flow.component.login.testbench.LoginOverlayElement; +import com.vaadin.testbench.ElementQuery; +import com.vaadin.testbench.TestBenchElement; public class LoginLayoutIT extends AbstractViewTest { public LoginLayoutIT() { - super("extended-login/login-layout"); + super("it/extended-login/login-layout"); } @Test public void testBasicBehaviour() { - VaadinLoginOverlayWrapperElement vlow = $(VaadinLoginOverlayWrapperElement.class).first(); - VaadinLoginFormWrapperElement vlfw = $(VaadinLoginFormWrapperElement.class).first(); + boolean vaadin25 = $server.getMajorVersion() >= 25; + + LoginOverlayElement vlo = $(LoginOverlayElement.class).first(); + TestBenchElement vlow = vaadin25 ? vlo.getLoginOverlayWrapper() : $(VaadinLoginOverlayWrapperElement.class).first(); + TestBenchElement vlfw = vaadin25 ? vlo.$("vaadin-login-form-wrapper").first() + : $(VaadinLoginFormWrapperElement.class).first(); + assertTrue( "Custom image is not present", vlow.$(ImageElement.class).attribute("alt", "Login image").exists()); - boolean h2exists = vlfw.$(H2Element.class).exists(); - assertTrue("H2 is not present", h2exists); - if (h2exists) { - assertEquals("Change Password", vlfw.$(H2Element.class).first().getText()); + + if (vaadin25) { + assertEquals("Change Password", vlo.getFormTitle()); + } else { + boolean h2exists = vlfw.$(H2Element.class).exists(); + assertTrue("H2 is not present", h2exists); + if (h2exists) { + assertEquals("Change Password", vlfw.$(H2Element.class).first().getText()); + } } - boolean divSlotFormExists = $(DivElement.class).attribute("slot", "form").exists(); + + ElementQuery divSlotForm = vlfw.$(DivElement.class).attribute("slot", "form"); + boolean divSlotFormExists = divSlotForm.exists(); assertTrue("Div with slot form is not present", divSlotFormExists); if (divSlotFormExists) { - boolean divContainsFormLayoutExists = - $(DivElement.class).attribute("slot", "form").first().$(FormLayoutElement.class).exists(); + boolean divContainsFormLayoutExists = divSlotForm.first().$(FormLayoutElement.class).exists(); assertTrue("Div does not contain form layout", divContainsFormLayoutExists); } } + } diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java new file mode 100644 index 0000000..5b8c61c --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java @@ -0,0 +1,31 @@ +/*- + * #%L + * Extended Login Add-on + * %% + * Copyright (C) 2023 - 2026 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.extendedlogin.it; + +/** + * Interface for callable methods to retrieve server version information. This + * is used to determine whether certain tests should be executed based on the + * server version. + */ +public interface ServerVersionCallables { + + int getMajorVersion(); + +} \ No newline at end of file diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestExtendedLoginOverlayIntegrationView.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestExtendedLoginOverlayIntegrationView.java new file mode 100644 index 0000000..e5049e4 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestExtendedLoginOverlayIntegrationView.java @@ -0,0 +1,38 @@ +/*- + * #%L + * Extended Login Add-on + * %% + * Copyright (C) 2023 - 2026 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.extendedlogin.it; + +import com.flowingcode.vaadin.addons.extendedlogin.TestExtendedLoginOverlayView; +import com.vaadin.flow.component.ClientCallable; +import com.vaadin.flow.router.Route; + +/** + * Integration test view for {@link TestExtendedLoginOverlayView}. + */ +@Route("it/extended-login/login-overlay") +public class TestExtendedLoginOverlayIntegrationView extends TestExtendedLoginOverlayView implements ServerVersionCallables { + + @Override + @ClientCallable + public int getMajorVersion() { + return com.vaadin.flow.server.Version.getMajorVersion(); + } + +} diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegration.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegration.java new file mode 100644 index 0000000..a141ad7 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegration.java @@ -0,0 +1,37 @@ +/*- + * #%L + * Extended Login Add-on + * %% + * Copyright (C) 2023 - 2026 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.extendedlogin.it; + +import com.flowingcode.vaadin.addons.extendedlogin.TestLoginLayout; +import com.vaadin.flow.component.ClientCallable; + +/** + * Integration test view for {@link TestLoginLayout}. + */ +public class TestLoginLayoutIntegration extends TestLoginLayout + implements ServerVersionCallables { + + @Override + @ClientCallable + public int getMajorVersion() { + return com.vaadin.flow.server.Version.getMajorVersion(); + } + +} diff --git a/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegrationView.java b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegrationView.java new file mode 100644 index 0000000..2e903c5 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegrationView.java @@ -0,0 +1,32 @@ +/*- + * #%L + * Extended Login Add-on + * %% + * Copyright (C) 2023 - 2026 Flowing Code + * %% + * 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. + * #L% + */ +package com.flowingcode.vaadin.addons.extendedlogin.it; + +import com.flowingcode.vaadin.addons.extendedlogin.TestLoginLayout; +import com.flowingcode.vaadin.addons.extendedlogin.TestLoginLayoutView; +import com.vaadin.flow.router.Route; + +/** + * Integration test view for {@link TestLoginLayout}. + */ +@Route(value = "it/extended-login/login-layout", layout = TestLoginLayoutIntegration.class) +public class TestLoginLayoutIntegrationView extends TestLoginLayoutView { + +} From 56460c00f139834264926b4d5169c72bb3648f74 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Fri, 6 Mar 2026 16:39:50 -0300 Subject: [PATCH 7/7] ci: update Vaadin version to 25.0.6 in v25 profile --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ac5538d..b2f1a7b 100644 --- a/pom.xml +++ b/pom.xml @@ -466,7 +466,7 @@ 21 21 - 25.0.0 + 25.0.6 11.0.26