diff --git a/README.md b/README.md index e017ced..e83c06e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -##GwtChosen +##GwtChosen [Chosen](https://github.com/harvesthq/chosen) is a javascript plugin (for jQuery and Prototype) _that makes long, unwieldy select boxes much more user-friendly._ GwtChosen is a port of the jquery version of Chosen for GWT Web Toolkit. It is not a wrapper but a complete rewrite using the GWT standards. It is available as a GwtQuery plugin or as a widget. ##Documentation @@ -52,10 +52,15 @@ Find the the available jars in [Maven Central](http://search.maven.org/#search%7 * General IDEA and Eclipse project import instructions can be found [here](http://c.gwt-examples.com/home/maven/ide-import). * If using Eclipse double check the GwtChosen GPE plugin and see if GWT is enabled. +##Debugging integration tests locally +1. `cd integration-test` +2. `mvn gwt:run -Pintegration-test` +3. Open your browser to `http://127.0.0.1:8080/#{test case token}` + #FAQ ##Credits -* The initial chosen javascript plugin was built by [Harvest](http://www.getharvest.com/). -* Concept and development by [Patrick Filler](http://patrickfiller.com/). +* The initial chosen javascript plugin was built by [Harvest](http://www.getharvest.com/). +* Concept and development by [Patrick Filler](http://patrickfiller.com/). * Design and CSS by [Matthew Lettini](http://matthewlettini.com/) * The GWT port of Chosen was built by [Julien Dramaix](https://plus.google.com/u/0/103916508880440628637) diff --git a/integration-test/pom.xml b/integration-test/pom.xml index c656161..c093a36 100644 --- a/integration-test/pom.xml +++ b/integration-test/pom.xml @@ -55,6 +55,10 @@ org.codehaus.mojo gwt-maven-plugin ${gwt.version} + + index.html + 8080 + diff --git a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/ChosenSampleIntegrationTests.java b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/ChosenSampleIntegrationTests.java index 84230ba..b4b8909 100644 --- a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/ChosenSampleIntegrationTests.java +++ b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/ChosenSampleIntegrationTests.java @@ -16,28 +16,45 @@ package com.arcbees.chosen.integrationtest.client; -import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; -import com.arcbees.chosen.client.gwt.ChosenValueListBox; -import com.google.common.base.CaseFormat; +import com.arcbees.chosen.integrationtest.client.testcases.ChooseOption; +import com.arcbees.chosen.integrationtest.client.testcases.HideEmptyValues; +import com.arcbees.chosen.integrationtest.client.testcases.ShowNonEmptyValues; import com.google.gwt.core.client.EntryPoint; -import com.google.gwt.text.shared.AbstractRenderer; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; +import com.google.gwt.user.client.History; import com.google.gwt.user.client.ui.RootPanel; -public class ChosenSampleIntegrationTests implements EntryPoint { +public class ChosenSampleIntegrationTests implements EntryPoint, ValueChangeHandler { + private final Map testCaseMap; + + public ChosenSampleIntegrationTests() { + testCaseMap = new HashMap(); + registerTestCase(new ChooseOption()); + registerTestCase(new HideEmptyValues()); + registerTestCase(new ShowNonEmptyValues()); + } + + private void registerTestCase(TestCase testCase) { + assert !testCaseMap.containsKey(testCase.getToken()); + + testCaseMap.put(testCase.getToken(), testCase); + } + @Override public void onModuleLoad() { - RootPanel rootPanel = RootPanel.get(); - ChosenValueListBox listBox = new ChosenValueListBox(new AbstractRenderer() { - @Override - public String render(CarBrand object) { - return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, object.name()); - } - }); - - listBox.setAcceptableValues(EnumSet.allOf(CarBrand.class)); - listBox.setValue(CarBrand.AUDI); - - rootPanel.add(listBox); + History.addValueChangeHandler(this); + History.fireCurrentHistoryState(); + } + + @Override + public void onValueChange(ValueChangeEvent event) { + RootPanel.get().clear(); + String token = event.getValue(); + TestCase testCase = testCaseMap.get(token); + testCase.run(); } } diff --git a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/CarBrand.java b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/TestCase.java similarity index 73% rename from integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/CarBrand.java rename to integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/TestCase.java index cfdb986..6958436 100644 --- a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/CarBrand.java +++ b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/TestCase.java @@ -16,22 +16,8 @@ package com.arcbees.chosen.integrationtest.client; -public enum CarBrand { - TOYOTA, - HONDA, - MERCEDES, - FORD, - HYUNDAI, - FERRARI, - BMW, - TESLA, - AUDI, - BENTLEY, - CADILLAC, - CHEVROLET, - CHRYSLER, - DODGE, - MITSUBISHI, - JAGUAR, - JEEP +public abstract class TestCase implements Runnable { + public String getToken() { + return getClass().getSimpleName(); + } } diff --git a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/domain/CarBrand.java b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/domain/CarBrand.java new file mode 100644 index 0000000..a989c1d --- /dev/null +++ b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/domain/CarBrand.java @@ -0,0 +1,51 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * 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.arcbees.chosen.integrationtest.client.domain; + +import java.util.HashSet; +import java.util.Set; + +import com.google.gwt.text.shared.Renderer; + +public enum CarBrand { + TOYOTA, + HONDA, + MERCEDES, + FORD, + HYUNDAI, + FERRARI, + BMW, + TESLA, + AUDI, + BENTLEY, + CADILLAC, + CHEVROLET, + CHRYSLER, + DODGE, + MITSUBISHI, + JAGUAR, + JEEP; + + public static Set getAllNames(Renderer renderer) { + Set brandNames = new HashSet(); + for (CarBrand carBrand : CarBrand.values()) { + brandNames.add(renderer.render(carBrand)); + } + + return brandNames; + } +} diff --git a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/ChooseOption.java b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/ChooseOption.java new file mode 100644 index 0000000..1917f91 --- /dev/null +++ b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/ChooseOption.java @@ -0,0 +1,49 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * 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.arcbees.chosen.integrationtest.client.testcases; + +import java.util.EnumSet; + +import com.arcbees.chosen.client.gwt.ChosenValueListBox; +import com.arcbees.chosen.integrationtest.client.TestCase; +import com.arcbees.chosen.integrationtest.client.domain.CarBrand; +import com.google.gwt.text.shared.AbstractRenderer; +import com.google.gwt.user.client.ui.RootPanel; + +public class ChooseOption extends TestCase { + public static final AbstractRenderer RENDERER = new AbstractRenderer() { + @Override + public String render(CarBrand object) { + if (object == null) { + return ""; + } + return object.name(); + } + }; + + @Override + public void run() { + RootPanel rootPanel = RootPanel.get(); + + ChosenValueListBox listBox = new ChosenValueListBox(RENDERER); + + listBox.setAcceptableValues(EnumSet.allOf(CarBrand.class)); + listBox.setValue(CarBrand.AUDI); + + rootPanel.add(listBox); + } +} diff --git a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/HideEmptyValues.java b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/HideEmptyValues.java new file mode 100644 index 0000000..67cf741 --- /dev/null +++ b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/HideEmptyValues.java @@ -0,0 +1,57 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * 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.arcbees.chosen.integrationtest.client.testcases; + +import java.util.List; + +import com.arcbees.chosen.client.gwt.ChosenValueListBox; +import com.arcbees.chosen.integrationtest.client.TestCase; +import com.arcbees.chosen.integrationtest.client.domain.CarBrand; +import com.google.common.collect.Lists; +import com.google.gwt.text.shared.AbstractRenderer; +import com.google.gwt.text.shared.Renderer; +import com.google.gwt.user.client.ui.RootPanel; + +/** + * This test makes sure that when null values are rendered as empty string (""), + * then the empty string will not be displayed in the dropdown options. + */ + +public class HideEmptyValues extends TestCase { + public static final Renderer RENDERER = new AbstractRenderer() { + @Override + public String render(CarBrand object) { + if (object == null) { + return ""; + } + return object.name(); + } + }; + + @Override + public void run() { + ChosenValueListBox listBox = new ChosenValueListBox(RENDERER); + + List carBrands = Lists.newArrayList(CarBrand.values()); + carBrands.add(0, null); + listBox.setAcceptableValues(carBrands); + + listBox.setValue(null); + + RootPanel.get().add(listBox); + } +} diff --git a/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/ShowNonEmptyValues.java b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/ShowNonEmptyValues.java new file mode 100644 index 0000000..e35ea62 --- /dev/null +++ b/integration-test/src/main/java/com/arcbees/chosen/integrationtest/client/testcases/ShowNonEmptyValues.java @@ -0,0 +1,57 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * 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.arcbees.chosen.integrationtest.client.testcases; + +import java.util.List; + +import com.arcbees.chosen.client.gwt.ChosenValueListBox; +import com.arcbees.chosen.integrationtest.client.TestCase; +import com.arcbees.chosen.integrationtest.client.domain.CarBrand; +import com.google.common.collect.Lists; +import com.google.gwt.text.shared.AbstractRenderer; +import com.google.gwt.text.shared.Renderer; +import com.google.gwt.user.client.ui.RootPanel; + +/** + * This test makes sure that when null values are rendered as a non-empty string, + * then that exact non-empty string will be displayed in the dropdown options. + */ + +public class ShowNonEmptyValues extends TestCase { + public static final Renderer RENDERER = new AbstractRenderer() { + @Override + public String render(CarBrand object) { + if (object == null) { + return "Placeholder for null"; + } + return object.name(); + } + }; + + @Override + public void run() { + ChosenValueListBox listBox = new ChosenValueListBox(RENDERER); + + List carBrands = Lists.newArrayList(CarBrand.values()); + carBrands.add(0, null); + listBox.setAcceptableValues(carBrands); + + listBox.setValue(null); + + RootPanel.get().add(listBox); + } +} diff --git a/integration-test/src/test/java/SampleIT.java b/integration-test/src/test/java/SampleIT.java index 959bbd8..9b20e56 100644 --- a/integration-test/src/test/java/SampleIT.java +++ b/integration-test/src/test/java/SampleIT.java @@ -14,6 +14,9 @@ * the License. */ +import java.util.List; +import java.util.Set; + import org.junit.After; import org.junit.Test; import org.openqa.selenium.By; @@ -23,21 +26,55 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; +import com.arcbees.chosen.integrationtest.client.TestCase; +import com.arcbees.chosen.integrationtest.client.domain.CarBrand; +import com.arcbees.chosen.integrationtest.client.testcases.ChooseOption; +import com.arcbees.chosen.integrationtest.client.testcases.HideEmptyValues; +import com.arcbees.chosen.integrationtest.client.testcases.ShowNonEmptyValues; +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + import static org.assertj.core.api.Assertions.assertThat; +import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable; +import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfAllElementsLocatedBy; +import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated; + +import static com.arcbees.chosen.integrationtest.client.domain.CarBrand.FORD; public class SampleIT { private static final String ROOT = "http://localhost:8080"; - - private final WebDriver webDriver = new ChromeDriver(); private static final int TIME_OUT_IN_SECONDS = 20; + private final WebDriver webDriver = new ChromeDriver(); + + @Test + public void chooseOption() throws Throwable { + loadTestCase(new ChooseOption()); + String fordRender = ChooseOption.RENDERER.render(FORD); + + clickOptionWithDisplayString(fordRender); + + assertThat(getSelectedOptionText()).isEqualTo(fordRender); + } + + @Test + public void hideEmptyValues() { + loadTestCase(new HideEmptyValues()); + + Set options = getOptions(); + + assertThat(options).isEqualTo(CarBrand.getAllNames(HideEmptyValues.RENDERER)); + } @Test - public void sampleTest() throws Throwable { - webDriver.get(ROOT); + public void showNonEmptyValues() { + loadTestCase(new ShowNonEmptyValues()); - clickElementWithDisplayString("Ford"); + Set options = getOptions(); - assertThat(getSelectedValueText()).isEqualTo("Ford"); + Set allNames = CarBrand.getAllNames(ShowNonEmptyValues.RENDERER); + allNames.add(ShowNonEmptyValues.RENDERER.render(null)); + assertThat(options).isEqualTo(allNames); } @After @@ -45,29 +82,44 @@ public void after() { webDriver.quit(); } + private Set getOptions() { + String xpath = "//ul/li"; + List options = webDriverWait().until(presenceOfAllElementsLocatedBy(By.xpath(xpath))); + return Sets.newHashSet(Lists.transform(options, new Function() { + @Override + public String apply(WebElement input) { + return input.getText(); + } + })); + } + private WebDriverWait webDriverWait() { return new WebDriverWait(webDriver, TIME_OUT_IN_SECONDS); } - private void clickElementWithDisplayString(String displayString) { + private void clickOptionWithDisplayString(String displayString) { openDropDown(); - WebElement li = webDriverWait().until(ExpectedConditions.presenceOfElementLocated( - By.xpath(String.format("//li[text()='%s']", displayString)))); + String xpath = String.format("//li[text()='%s']", displayString); + WebElement li = webDriverWait().until(presenceOfElementLocated(By.xpath(xpath))); li.click(); } private void openDropDown() { - WebElement btn = webDriverWait().until(ExpectedConditions.elementToBeClickable(By.xpath - ("//div[@id='chozen_container__0_chzn']/a"))); + String xpath = "//div[@id='chozen_container__0_chzn']/a"; + WebElement btn = webDriverWait().until(elementToBeClickable(By.xpath(xpath))); btn.click(); } - private String getSelectedValueText() { - WebElement span = webDriverWait().until(ExpectedConditions.visibilityOfElementLocated(By.xpath - ("//div[@id='chozen_container__0_chzn']/a/span"))); + private String getSelectedOptionText() { + String xpath = "//div[@id='chozen_container__0_chzn']/a/span"; + WebElement span = webDriverWait().until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath))); return span.getText(); } + + private void loadTestCase(TestCase testCase) { + webDriver.get(ROOT + "/#" + testCase.getToken()); + } }