From 9baee709ab53251df0e323e92891dad635dd0340 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 18 Jul 2018 13:24:40 +0300 Subject: [PATCH] Add theme variants demo and test helpers. (#4412) --- .../vaadin/flow/demo/ComponentDemoTest.java | 92 +++++++++++++++++++ .../java/com/vaadin/flow/demo/DemoView.java | 82 ++++++++++++++++- 2 files changed, 170 insertions(+), 4 deletions(-) diff --git a/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/ComponentDemoTest.java b/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/ComponentDemoTest.java index fda341b0d4e..5360d280b69 100644 --- a/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/ComponentDemoTest.java +++ b/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/ComponentDemoTest.java @@ -15,12 +15,23 @@ */ package com.vaadin.flow.demo; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.junit.Assert; import org.junit.Before; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import com.vaadin.flow.testutil.ChromeBrowserTest; +import static com.vaadin.flow.demo.DemoView.COMPONENT_WITH_VARIANTS_ID; +import static com.vaadin.flow.demo.DemoView.VARIANT_TOGGLE_BUTTONS_DIV_ID; + /** * Base class for the integration tests of component demos. * @@ -43,4 +54,85 @@ public void openDemoPageAndCheckForErrors() { layout = findElement(By.className("demo-view")); checkLogsForErrors(); } + + /** + * Verifies variants functionality for the current layout. + * + * The test will fail if a specific variant demo is not added first with + * {@link DemoView#addVariantsDemo(Supplier, BiConsumer, BiConsumer, Function, Enum[])} + * method. + */ + protected void verifyThemeVariantsBeingToggled() { + List toggleThemeButtons = layout + .findElement(By.id(VARIANT_TOGGLE_BUTTONS_DIV_ID)) + .findElements(By.tagName("button")); + Assert.assertFalse( + "Expected at least one toggle theme button in 'buttonDiv', but got none", + toggleThemeButtons.isEmpty()); + toggleThemeButtons.forEach(button -> toggleVariantAndCheck( + layout.findElement(By.id(COMPONENT_WITH_VARIANTS_ID)), button)); + } + + private void toggleVariantAndCheck(WebElement component, + WebElement button) { + List initialButtonThemes = getComponentThemes(component); + String initialButtonText = button.getText(); + + button.click(); + verifyThemeIsToggled(getComponentThemes(component), button.getText(), + initialButtonThemes, initialButtonText); + + button.click(); + Assert.assertEquals( + "After two toggle variants button clicks, button text should be the same as before testing", + button.getText(), initialButtonText); + + List currentThemes = getComponentThemes(component); + String assertionMessage = "After two toggle variants button clicks, component 'theme' attribute should contain the same value as before testing"; + Assert.assertEquals(assertionMessage, currentThemes.size(), + initialButtonThemes.size()); + currentThemes.forEach(currentTheme -> Assert.assertTrue( + assertionMessage + String.format( + " but theme variant '%s' is missing", currentTheme), + initialButtonThemes.contains(currentTheme))); + + } + + private void verifyThemeIsToggled(List updatedThemes, + String updatedButtonText, List previousThemes, + String previousButtonText) { + Assert.assertNotEquals("Button should change its text after toggling", + previousButtonText, updatedButtonText); + + boolean shouldAddTheme = previousButtonText.startsWith("Add"); + if (shouldAddTheme) { + Assert.assertTrue( + "When a theme variant got added, toggle button text should start with 'Remove' word", + updatedButtonText.startsWith("Remove")); + Assert.assertEquals( + "When a theme variant got added, component 'theme' attribute should contain one more variant that before", + previousThemes.size() + 1, updatedThemes.size()); + Assert.assertTrue( + "When a theme variant got added, component 'theme' attribute should contain all previous theme variants", + updatedThemes.containsAll(previousThemes)); + } else { + Assert.assertTrue( + "When a theme variant got removed, toggle button text should start with 'Add' word", + updatedButtonText.startsWith("Add")); + Assert.assertEquals( + "When a theme variant got removed, component 'theme' attribute should contain one less variant than before", + previousThemes.size() - 1, updatedThemes.size()); + Assert.assertTrue( + "When a theme variant got removed, previous theme variants should contain all theme variants from component 'theme' attribute", + previousThemes.containsAll(updatedThemes)); + } + } + + private List getComponentThemes(WebElement component) { + String themeAttributeValue = component.getAttribute("theme"); + if (themeAttributeValue == null || themeAttributeValue.isEmpty()) { + return Collections.emptyList(); + } + return Arrays.asList(themeAttributeValue.split(" ")); + } } diff --git a/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/DemoView.java b/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/DemoView.java index 8a425d3c6e6..04cb990b2e2 100644 --- a/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/DemoView.java +++ b/flow-components-parent/flow-component-demo-helpers/src/main/java/com/vaadin/flow/demo/DemoView.java @@ -19,16 +19,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; import com.vaadin.flow.component.AttachEvent; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.HasComponents; import com.vaadin.flow.component.HasStyle; +import com.vaadin.flow.component.HasTheme; import com.vaadin.flow.component.Tag; import com.vaadin.flow.component.dependency.JavaScript; 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.NativeButton; import com.vaadin.flow.router.BeforeEvent; import com.vaadin.flow.router.HasUrlParameter; import com.vaadin.flow.router.OptionalParameter; @@ -49,12 +54,14 @@ @JavaScript("src/script/prism.js") public abstract class DemoView extends Component implements HasComponents, HasUrlParameter, HasStyle { + static final String VARIANT_TOGGLE_BUTTONS_DIV_ID = "variantToggleButtonsDiv"; + static final String COMPONENT_WITH_VARIANTS_ID = "componentWithVariantsDemo"; - private DemoNavigationBar navBar = new DemoNavigationBar(); - private Div container = new Div(); + private final DemoNavigationBar navBar = new DemoNavigationBar(); + private final Div container = new Div(); - private Map tabComponents = new HashMap<>(); - private Map> sourceCodeExamples = new HashMap<>(); + private final Map tabComponents = new HashMap<>(); + private final Map> sourceCodeExamples = new HashMap<>(); protected DemoView() { Route annotation = getClass().getAnnotation(Route.class); @@ -211,4 +218,71 @@ public void setParameter(BeforeEvent event, @OptionalParameter String parameter) { showTab(parameter == null ? "" : parameter); } + + /** + * Adds a demo that shows how the component looks like with specific + * variants applied. + * + * @param componentSupplier + * a method that creates the component to which variants will be + * applied to + * @param addVariant + * a function that adds the new variant to the component + * @param removeVariant + * a function that removes the variant from the component + * @param variantToThemeName + * function that converts variant to an html theme name + * @param variants + * list of variants to show in the demos + * @param + * variants' type + * @param + * component's type + */ + protected , C extends Component & HasTheme> void addVariantsDemo( + Supplier componentSupplier, BiConsumer addVariant, + BiConsumer removeVariant, + Function variantToThemeName, T... variants) { + + C component = componentSupplier.get(); + component.setId(COMPONENT_WITH_VARIANTS_ID); + + Div message = new Div(); + message.setText( + "Toggle a variant to see how the component's appearance will change."); + + Div variantsToggles = new Div(); + variantsToggles.setId(VARIANT_TOGGLE_BUTTONS_DIV_ID); + for (T variant : variants) { + if (variant.name().startsWith("LUMO_")) { + String variantName = variantToThemeName.apply(variant); + variantsToggles + .add(new NativeButton( + getButtonText(variantName, + component.getThemeNames() + .contains(variantName)), + event -> { + boolean variantPresent = component + .getThemeNames() + .contains(variantName); + if (variantPresent) { + removeVariant.accept(component, + variant); + } else { + addVariant.accept(component, variant); + } + event.getSource().setText(getButtonText( + variantName, !variantPresent)); + })); + + } + } + addCard("Theme variants usage", message, component, variantsToggles); + } + + private String getButtonText(String variantName, boolean variantPresent) { + return String.format( + variantPresent ? "Remove '%s' variant" : "Add '%s' variant", + variantName); + } }