diff --git a/pom.xml b/pom.xml index 9172d331517..467fc4e7368 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ vaadin-avatar-flow-parent vaadin-app-layout-flow-parent vaadin-aura-theme-flow-parent + vaadin-badge-flow-parent vaadin-button-flow-parent vaadin-card-flow-parent vaadin-checkbox-flow-parent diff --git a/vaadin-badge-flow-parent/pom.xml b/vaadin-badge-flow-parent/pom.xml new file mode 100644 index 00000000000..b8cbe4c4b55 --- /dev/null +++ b/vaadin-badge-flow-parent/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + com.vaadin + vaadin-flow-components + 25.0-SNAPSHOT + + vaadin-badge-flow-parent + pom + Vaadin Badge Parent + Vaadin Badge Parent + + vaadin-badge-flow + vaadin-badge-testbench + + + + + default + + + !release + + + + vaadin-badge-flow-integration-tests + + + + diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/pom.xml b/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/pom.xml new file mode 100644 index 00000000000..12915d42967 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/pom.xml @@ -0,0 +1,156 @@ + + + 4.0.0 + + com.vaadin + vaadin-badge-flow-parent + 25.0-SNAPSHOT + + vaadin-badge-integration-tests + war + Vaadin Badge Integration Tests + Vaadin Badge Integration Tests + + + com.vaadin + flow-client + + + com.vaadin + flow-data + + + com.vaadin + flow-html-components + + + com.vaadin + flow-test-util + test + + + com.vaadin + vaadin-badge-flow + ${project.version} + + + com.vaadin + vaadin-badge-testbench + ${project.version} + test + + + com.vaadin + vaadin-dev-server + + + com.vaadin + vaadin-flow-components-test-util + ${project.version} + test + + + com.vaadin + vaadin-lumo-theme + + + com.vaadin + vaadin-testbench-core + test + + + org.slf4j + slf4j-simple + + + + + + maven-clean-plugin + + + + ${project.basedir} + + package*.json + pnpm* + vite.generated.ts + types.d.ts + tsconfig.json + frontend/routes.tsx + frontend/App.tsx + + + + ${project.basedir}/node_modules + ${project.basedir}/frontend/generated + + + + + + maven-failsafe-plugin + + + maven-resources-plugin + + + org.sonatype.plugins + nexus-staging-maven-plugin + + true + + + + org.codehaus.mojo + properties-maven-plugin + + + maven-install-plugin + + true + + + + + + + build-frontend + + + !skipFrontend + + + + + + com.vaadin + flow-maven-plugin + + ./frontend + + + + + + + run-jetty + + + !skipJetty + + + + + + org.eclipse.jetty.ee10 + jetty-ee10-maven-plugin + + 5 + + + + + + + diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/src/main/java/com/vaadin/flow/component/badge/tests/BadgePage.java b/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/src/main/java/com/vaadin/flow/component/badge/tests/BadgePage.java new file mode 100644 index 00000000000..9ac327fd620 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/src/main/java/com/vaadin/flow/component/badge/tests/BadgePage.java @@ -0,0 +1,225 @@ +/* + * Copyright 2000-2025 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.component.badge.tests; + +import com.vaadin.flow.component.badge.Badge; +import com.vaadin.flow.component.badge.BadgeVariant; +import com.vaadin.flow.component.dependency.StyleSheet; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.component.html.H3; +import com.vaadin.flow.component.html.Hr; +import com.vaadin.flow.component.html.Span; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.theme.lumo.Lumo; + +/** + * Comprehensive visual test page for the Badge component showing all variants, + * sizes, colors, and use cases. + */ +@Route("vaadin-badge") +// Currently only Lumo is supported +@StyleSheet(Lumo.STYLESHEET) +public class BadgePage extends Div { + + public BadgePage() { + setWidthFull(); + getStyle().set("padding", "20px"); + + add(new H3("Badge Component - Visual Test Page")); + + + Span rawOldStyleSpanBadge = new Span(new Span("Pending")); + rawOldStyleSpanBadge.getElement().getThemeList().add("badge"); + + add(rawOldStyleSpanBadge); + + + // Basic badges + add(new H3("Basic Badges")); + Div basicSection = createSection(); + basicSection.add(new Badge("Default")); + basicSection.add(new Badge("New")); + basicSection.add(new Badge("Beta")); + basicSection.add(new Badge("123")); + add(basicSection); + + add(new Hr()); + + // Color variants + add(new H3("Color Variants")); + Div colorSection = createSection(); + + Badge primary = new Badge("Primary"); + primary.addThemeVariants(BadgeVariant.LUMO_PRIMARY); + primary.setId("badge-primary"); + colorSection.add(primary); + + Badge success = new Badge("Success"); + success.addThemeVariants(BadgeVariant.LUMO_SUCCESS); + success.setId("badge-success"); + colorSection.add(success); + + Badge warning = new Badge("Warning"); + warning.addThemeVariants(BadgeVariant.LUMO_WARNING); + warning.setId("badge-warning"); + colorSection.add(warning); + + Badge error = new Badge("Error"); + error.addThemeVariants(BadgeVariant.LUMO_ERROR); + error.setId("badge-error"); + colorSection.add(error); + + Badge contrast = new Badge("Contrast"); + contrast.addThemeVariants(BadgeVariant.LUMO_CONTRAST); + contrast.setId("badge-contrast"); + colorSection.add(contrast); + + add(colorSection); + + add(new Hr()); + + // Small size variant + add(new H3("Small Size")); + Div smallSection = createSection(); + + Badge smallDefault = new Badge("Small"); + smallDefault.addThemeVariants(BadgeVariant.LUMO_SMALL); + smallDefault.setId("badge-small"); + smallSection.add(smallDefault); + + Badge smallPrimary = new Badge("Small Primary"); + smallPrimary.addThemeVariants(BadgeVariant.LUMO_SMALL, + BadgeVariant.LUMO_PRIMARY); + smallSection.add(smallPrimary); + + Badge smallSuccess = new Badge("Small Success"); + smallSuccess.addThemeVariants(BadgeVariant.LUMO_SMALL, + BadgeVariant.LUMO_SUCCESS); + smallSection.add(smallSuccess); + + add(smallSection); + + add(new Hr()); + + // Pill shape variant + add(new H3("Pill Shape")); + Div pillSection = createSection(); + + Badge pill = new Badge("Pill"); + pill.addThemeVariants(BadgeVariant.LUMO_PILL); + pill.setId("badge-pill"); + pillSection.add(pill); + + Badge pillPrimary = new Badge("99+"); + pillPrimary.addThemeVariants(BadgeVariant.LUMO_PILL, + BadgeVariant.LUMO_PRIMARY); + pillSection.add(pillPrimary); + + Badge pillSmall = new Badge("3"); + pillSmall.addThemeVariants(BadgeVariant.LUMO_PILL, + BadgeVariant.LUMO_SMALL, BadgeVariant.LUMO_ERROR); + pillSection.add(pillSmall); + + add(pillSection); + + add(new Hr()); + + // Badges with components + add(new H3("Badges with Components")); + Div componentSection = createSection(); + + Badge withSpan = new Badge(); + withSpan.add(new Span("Status: "), new Span("Active")); + withSpan.addThemeVariants(BadgeVariant.LUMO_SUCCESS); + withSpan.setId("badge-with-components"); + componentSection.add(withSpan); + + Badge multiComponent = new Badge(); + multiComponent.add(new Span("Count: "), new Span("42")); + multiComponent.addThemeVariants(BadgeVariant.LUMO_PRIMARY); + componentSection.add(multiComponent); + + add(componentSection); + + add(new Hr()); + + // Accessibility examples + add(new H3("Accessibility Features")); + Div accessibilitySection = createSection(); + + Badge withAriaLabel = new Badge("!"); + withAriaLabel.setAriaLabel("Important notification"); + withAriaLabel.addThemeVariants(BadgeVariant.LUMO_ERROR, + BadgeVariant.LUMO_PILL); + withAriaLabel.setId("badge-aria-label"); + accessibilitySection.add(withAriaLabel); + + Badge withTooltip = new Badge("?"); + withTooltip.setTooltipText("This is a help badge"); + withTooltip.addThemeVariants(BadgeVariant.LUMO_CONTRAST, + BadgeVariant.LUMO_PILL); + withTooltip.setId("badge-tooltip"); + accessibilitySection.add(withTooltip); + + add(accessibilitySection); + + add(new Hr()); + + // Real-world use cases + add(new H3("Real-world Use Cases")); + Div useCasesSection = createSection(); + + // Notification badge + Span bellIcon = new Span("🔔"); + Badge notificationBadge = new Badge("5"); + notificationBadge.addThemeVariants(BadgeVariant.LUMO_ERROR, + BadgeVariant.LUMO_SMALL, BadgeVariant.LUMO_PILL); + Div notificationExample = new Div(bellIcon, notificationBadge); + notificationExample.getStyle().set("display", "inline-flex") + .set("align-items", "center").set("gap", "5px"); + useCasesSection.add(notificationExample); + + // Status badge + Badge statusBadge = new Badge("Online"); + statusBadge.addThemeVariants(BadgeVariant.LUMO_SUCCESS, + BadgeVariant.LUMO_SMALL); + useCasesSection.add(statusBadge); + + // Count badge + Badge countBadge = new Badge("NEW"); + countBadge.addThemeVariants(BadgeVariant.LUMO_PRIMARY); + useCasesSection.add(countBadge); + + add(useCasesSection); + + add(new Hr()); + + // Empty badge (for dynamic content) + add(new H3("Empty Badge (Dynamic Content)")); + Badge emptyBadge = new Badge(); + emptyBadge.setId("empty-badge"); + add(emptyBadge); + } + + private Div createSection() { + Div section = new Div(); + section.getStyle().set("display", "flex").set("gap", "10px") + .set("flex-wrap", "wrap").set("align-items", "center") + .set("padding", "10px 0"); + return section; + } +} diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/src/test/java/com/vaadin/flow/component/badge/tests/BadgeIT.java b/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/src/test/java/com/vaadin/flow/component/badge/tests/BadgeIT.java new file mode 100644 index 00000000000..fc065112ff3 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow-integration-tests/src/test/java/com/vaadin/flow/component/badge/tests/BadgeIT.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2025 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.component.badge.tests; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.flow.component.badge.testbench.BadgeElement; +import com.vaadin.flow.testutil.TestPath; +import com.vaadin.tests.AbstractComponentIT; + +@TestPath("vaadin-badge") +public class BadgeIT extends AbstractComponentIT { + + private BadgeElement badge; + + @Before + public void init() { + open(); + badge = $(BadgeElement.class).id("badge-primary"); + } + + @Test + public void rendersBadgeComponent() { + boolean hasShadowRoot = (Boolean) executeScript( + "return arguments[0].shadowRoot !== null", badge); + String componentName = (String) executeScript( + "return arguments[0].tagName", + badge); + + Assert.assertFalse(hasShadowRoot); // there should be no + Assert.assertEquals("VAADIN-BADGE", componentName); + Assert.assertNotNull(badge.getText()); + Assert.assertFalse(badge.getText().isEmpty()); + } + + @Test + public void badgeHasThemeVariants() { + BadgeElement successBadge = $(BadgeElement.class) + .id("badge-success"); + String theme = successBadge.getAttribute("theme"); + Assert.assertTrue(theme.contains("success")); + } + + @Test + public void badgeCanBeSmall() { + BadgeElement smallBadge = $(BadgeElement.class).id("badge-small"); + String theme = smallBadge.getAttribute("theme"); + Assert.assertTrue(theme.contains("small")); + } + + @Test + public void badgeCanBePill() { + BadgeElement pillBadge = $(BadgeElement.class).id("badge-pill"); + String theme = pillBadge.getAttribute("theme"); + Assert.assertTrue(theme.contains("pill")); + } +} diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow/pom.xml b/vaadin-badge-flow-parent/vaadin-badge-flow/pom.xml new file mode 100644 index 00000000000..880d811f2ed --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + + com.vaadin + vaadin-badge-flow-parent + 25.0-SNAPSHOT + + vaadin-badge-flow + jar + Vaadin Badge + Vaadin Badge + + + com.vaadin + flow-html-components + provided + + + com.vaadin + flow-test-generic + test + + + com.vaadin + flow-test-util + test + + + com.vaadin + vaadin-flow-components-base + ${project.version} + + + com.vaadin + vaadin-flow-components-test-util + ${project.version} + test + + + jakarta.platform + jakarta.jakartaee-web-api + test + + + jakarta.servlet + jakarta.servlet-api + + + org.mockito + mockito-core + test + + + org.slf4j + slf4j-simple + test + + + + + + biz.aQute.bnd + bnd-maven-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + + + + attach-docs + + + with-docs + + + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.codehaus.mojo + build-helper-maven-plugin + + + + + + diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow/src/main/java/com/vaadin/flow/component/badge/Badge.java b/vaadin-badge-flow-parent/vaadin-badge-flow/src/main/java/com/vaadin/flow/component/badge/Badge.java new file mode 100644 index 00000000000..80b594e8870 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow/src/main/java/com/vaadin/flow/component/badge/Badge.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2025 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.component.badge; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.HasAriaLabel; +import com.vaadin.flow.component.HasComponents; +import com.vaadin.flow.component.HasSize; +import com.vaadin.flow.component.HasStyle; +import com.vaadin.flow.component.HasText; +import com.vaadin.flow.component.Tag; +import com.vaadin.flow.component.shared.HasThemeVariant; +import com.vaadin.flow.component.shared.HasTooltip; + +/** + * Badge is a colored text element for labeling content, displaying metadata, + * or highlighting information. Note, currently only Lumo theme supports badges. + *

+ * Badges are typically used to show statuses, categories, or counts. They + * support text content, icons, and various theme variants for different colors + * and sizes. + *

+ * + *

Usage Examples

+ * + *
+ * {@code
+ * // Simple badge with text
+ * Badge badge = new Badge("New");
+ *
+ * // Badge with theme variants
+ * Badge successBadge = new Badge("Success");
+ * successBadge.addThemeVariants(BadgeVariant.LUMO_SUCCESS);
+ *
+ * // Small pill-shaped badge
+ * Badge pillBadge = new Badge("3");
+ * pillBadge.addThemeVariants(BadgeVariant.LUMO_SMALL, BadgeVariant.LUMO_PILL);
+ *
+ * // Badge with icon
+ * Badge iconBadge = new Badge();
+ * iconBadge.add(new Icon(VaadinIcon.CHECK), new Span("Verified"));
+ * }
+ * 
+ * + *

Theme Variants

+ *

+ * The component supports several theme variants for styling: + *

+ * + * + *

Accessibility

+ *

+ * When using icon-only badges or when the badge's visual appearance alone + * doesn't convey the full meaning, use {@link #setAriaLabel(String)} to + * provide a text alternative for screen readers. Additionally, consider using + * {@link #setTooltipText(String)} to provide helpful information to all users. + *

+ * + * @author Vaadin Ltd + */ +@Tag("vaadin-badge") +public class Badge extends Component implements HasText, HasSize, HasStyle, + HasComponents, HasThemeVariant, HasTooltip, HasAriaLabel { + + /** + * Creates an empty badge. + *

+ * Use {@link #setText(String)} to set the badge text or {@link #add(Component...)} + * to add icons or other components. + *

+ */ + public Badge() { + getElement().getThemeList().add("badge"); + } + + /** + * Creates a badge with the specified text. + * + * @param text + * the text content of the badge + */ + public Badge(String text) { + this(); + setText(text); + } +} diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow/src/main/java/com/vaadin/flow/component/badge/BadgeVariant.java b/vaadin-badge-flow-parent/vaadin-badge-flow/src/main/java/com/vaadin/flow/component/badge/BadgeVariant.java new file mode 100644 index 00000000000..c8f3c0f6d62 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow/src/main/java/com/vaadin/flow/component/badge/BadgeVariant.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2025 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.component.badge; + +import com.vaadin.flow.component.shared.ThemeVariant; + +/** + * Set of theme variants applicable for {@code vaadin-badge} component. + */ +public enum BadgeVariant implements ThemeVariant { + //@formatter:off + LUMO_PRIMARY("primary"), + LUMO_SUCCESS("success"), + LUMO_WARNING("warning"), + LUMO_ERROR("error"), + LUMO_CONTRAST("contrast"), + LUMO_SMALL("small"), + LUMO_PILL("pill"), + AURA_PRIMARY("primary"), + AURA_SUCCESS("success"), + AURA_WARNING("warning"), + AURA_ERROR("error"), + AURA_CONTRAST("contrast"), + AURA_SMALL("small"), + AURA_PILL("pill"); + //@formatter:on + + private final String variant; + + BadgeVariant(String variant) { + this.variant = variant; + } + + /** + * Gets the variant name. + * + * @return variant name + */ + public String getVariantName() { + return variant; + } +} diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeSerializableTest.java b/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeSerializableTest.java new file mode 100644 index 00000000000..cccad5f0700 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeSerializableTest.java @@ -0,0 +1,21 @@ +/* + * Copyright 2000-2025 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.component.badge; + +import com.vaadin.flow.testutil.ClassesSerializableTest; + +public class BadgeSerializableTest extends ClassesSerializableTest { +} diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeTest.java b/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeTest.java new file mode 100644 index 00000000000..1efcc7ed1a7 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeTest.java @@ -0,0 +1,163 @@ +/* + * Copyright 2000-2025 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.component.badge; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.flow.component.UI; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.component.html.Span; + +/** + * Unit tests for the {@link Badge} component. + */ +public class BadgeTest { + + private Badge badge; + + @Before + public void setup() { + var ui = new UI(); + UI.setCurrent(ui); + badge = new Badge(); + ui.add(badge); + } + + @After + public void tearDown() { + UI.setCurrent(null); + } + + @Test + public void defaultConstructor_textIsEmpty() { + Assert.assertEquals("", badge.getText()); + } + + @Test + public void constructorWithText_textIsSet() { + var badgeWithText = new Badge("New"); + Assert.assertEquals("New", badgeWithText.getText()); + } + + @Test + public void setText_textIsUpdated() { + badge.setText("Updated"); + Assert.assertEquals("Updated", badge.getText()); + } + + @Test + public void setTextNull_textIsEmpty() { + badge.setText("Text"); + badge.setText(null); + Assert.assertEquals("", badge.getText()); + } + + @Test + public void addComponent_componentIsAdded() { + var span = new Span("Content"); + badge.add(span); + Assert.assertTrue(badge.getChildren().anyMatch(c -> c.equals(span))); + Assert.assertTrue(span.isAttached()); + } + + @Test + public void addMultipleComponents_allComponentsAreAdded() { + var span1 = new Span("First"); + var span2 = new Span("Second"); + badge.add(span1, span2); + Assert.assertEquals(2, badge.getChildren().count()); + Assert.assertTrue(badge.getChildren().anyMatch(c -> c.equals(span1))); + Assert.assertTrue(badge.getChildren().anyMatch(c -> c.equals(span2))); + } + + @Test + public void removeComponent_componentIsRemoved() { + var span = new Span("Content"); + badge.add(span); + badge.remove(span); + Assert.assertFalse(badge.getChildren().anyMatch(c -> c.equals(span))); + Assert.assertFalse(span.isAttached()); + } + + @Test + public void removeAll_allComponentsAreRemoved() { + badge.add(new Span("First"), new Span("Second")); + badge.removeAll(); + Assert.assertEquals(0, badge.getChildren().count()); + } + + @Test + public void addThemeVariant_variantIsAdded() { + badge.addThemeVariants(BadgeVariant.LUMO_SUCCESS); + Assert.assertTrue(badge.getThemeNames().contains("success")); + } + + @Test + public void addMultipleThemeVariants_allVariantsAreAdded() { + badge.addThemeVariants(BadgeVariant.LUMO_SUCCESS, + BadgeVariant.LUMO_SMALL); + Assert.assertTrue(badge.getThemeNames().contains("success")); + Assert.assertTrue(badge.getThemeNames().contains("small")); + } + + @Test + public void removeThemeVariant_variantIsRemoved() { + badge.addThemeVariants(BadgeVariant.LUMO_SUCCESS); + badge.removeThemeVariants(BadgeVariant.LUMO_SUCCESS); + Assert.assertFalse(badge.getThemeNames().contains("success")); + } + + @Test + public void setAriaLabel_ariaLabelIsSet() { + badge.setAriaLabel("Status badge"); + Assert.assertEquals("Status badge", badge.getAriaLabel().orElse(null)); + } + + @Test + public void setAriaLabelNull_ariaLabelIsRemoved() { + badge.setAriaLabel("Status badge"); + badge.setAriaLabel(null); + Assert.assertTrue(badge.getAriaLabel().isEmpty()); + } + + @Test + public void setTooltipText_tooltipIsSet() { + badge.setTooltipText("This is a badge"); + // Tooltip is set, we can't easily test the content but we can verify no exception + Assert.assertNotNull(badge); + } + + @Test + public void setWidth_widthIsSet() { + badge.setWidth("100px"); + Assert.assertEquals("100px", badge.getWidth()); + } + + @Test + public void setHeight_heightIsSet() { + badge.setHeight("50px"); + Assert.assertEquals("50px", badge.getHeight()); + } + + @Test + public void addClassName_classNameIsAdded() { + badge.addClassName("custom-badge"); + Assert.assertTrue(badge.getClassNames().contains("custom-badge")); + } +} diff --git a/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeVariantTest.java b/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeVariantTest.java new file mode 100644 index 00000000000..c1b1e825d5e --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-flow/src/test/java/com/vaadin/flow/component/badge/BadgeVariantTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2025 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.component.badge; + +import org.junit.Test; + +import com.vaadin.tests.ThemeVariantTestHelper; + +public class BadgeVariantTest { + + @Test + public void addThemeVariant_themeNamesContainsThemeVariant() { + ThemeVariantTestHelper.addThemeVariant_themeNamesContainsThemeVariant( + new Badge(), BadgeVariant.LUMO_SUCCESS); + } + + @Test + public void addThemeVariant_removeThemeVariant_themeNamesDoesNotContainThemeVariant() { + ThemeVariantTestHelper + .addThemeVariant_removeThemeVariant_themeNamesDoesNotContainThemeVariant( + new Badge(), BadgeVariant.LUMO_SUCCESS); + } +} diff --git a/vaadin-badge-flow-parent/vaadin-badge-testbench/pom.xml b/vaadin-badge-flow-parent/vaadin-badge-testbench/pom.xml new file mode 100644 index 00000000000..d13978060fd --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-testbench/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + com.vaadin + vaadin-badge-flow-parent + 25.0-SNAPSHOT + + vaadin-badge-testbench + jar + Vaadin Badge Testbench API + Vaadin Badge Testbench API + + + com.vaadin + vaadin-testbench-shared + provided + + + + + + + + attach-docs + + + with-docs + + + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + diff --git a/vaadin-badge-flow-parent/vaadin-badge-testbench/src/main/java/com/vaadin/flow/component/badge/testbench/BadgeElement.java b/vaadin-badge-flow-parent/vaadin-badge-testbench/src/main/java/com/vaadin/flow/component/badge/testbench/BadgeElement.java new file mode 100644 index 00000000000..46216d4f8f4 --- /dev/null +++ b/vaadin-badge-flow-parent/vaadin-badge-testbench/src/main/java/com/vaadin/flow/component/badge/testbench/BadgeElement.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2025 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.component.badge.testbench; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elementsbase.Element; + +/** + * A TestBench element representing a <vaadin-badge> + * element. + */ +@Element("vaadin-badge") +public class BadgeElement extends TestBenchElement { + + /** + * Gets the text content of the badge. + * + * @return the badge text + */ + public String getText() { + return getPropertyString("textContent"); + } +}