Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add theme variants demo and test helpers. #4412

Merged
merged 1 commit into from
Jul 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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<WebElement> 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<String> 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<String> 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<String> updatedThemes,
String updatedButtonText, List<String> 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());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR Cast one of the operands of this addition operation to a "long". rule

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());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR Cast one of the operands of this subtraction operation to a "long". rule

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<String> getComponentThemes(WebElement component) {
String themeAttributeValue = component.getAttribute("theme");
if (themeAttributeValue == null || themeAttributeValue.isEmpty()) {
return Collections.emptyList();
}
return Arrays.asList(themeAttributeValue.split(" "));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -49,12 +54,14 @@
@JavaScript("src/script/prism.js")
public abstract class DemoView extends Component
implements HasComponents, HasUrlParameter<String>, 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<String, Div> tabComponents = new HashMap<>();
private Map<String, List<SourceCodeExample>> sourceCodeExamples = new HashMap<>();
private final Map<String, Div> tabComponents = new HashMap<>();
private final Map<String, List<SourceCodeExample>> sourceCodeExamples = new HashMap<>();

protected DemoView() {
Route annotation = getClass().getAnnotation(Route.class);
Expand Down Expand Up @@ -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 <T>
* variants' type
* @param <C>
* component's type
*/
protected <T extends Enum<?>, C extends Component & HasTheme> void addVariantsDemo(
Supplier<C> componentSupplier, BiConsumer<C, T> addVariant,
BiConsumer<C, T> removeVariant,
Function<T, String> 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);
}
}