Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

change name

  • Loading branch information...
commit c3c84c79af9b6d21376e99950f58064ec02aab3a 1 parent c9071ca
@MathildeLemee MathildeLemee authored
Showing with 4,661 additions and 0 deletions.
  1. +22 −0 etc/jetty.xml
  2. +257 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/Fluent.java
  3. +64 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/FluentPage.java
  4. +49 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/action/FillConstructor.java
  5. +29 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/action/FluentDefaultActions.java
  6. +25 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/annotation/Page.java
  7. +219 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/domain/FluentList.java
  8. +192 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/domain/FluentWebElement.java
  9. +26 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/exception/ConstructionException.java
  10. +89 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/Filter.java
  11. +87 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterBuilder.java
  12. +175 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterConstructor.java
  13. +43 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterPredicate.java
  14. +24 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterType.java
  15. +172 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/MatcherConstructor.java
  16. +107 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/CalculateService.java
  17. +42 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/ContainsMatcher.java
  18. +40 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/EndsWithMatcher.java
  19. +40 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/EqualMatcher.java
  20. +82 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/Matcher.java
  21. +39 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/MatcherType.java
  22. +40 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/NotContainsMatcher.java
  23. +40 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/NotEndsWithMatcher.java
  24. +40 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/NotStartsWithMatcher.java
  25. +49 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/StartsWithMatcher.java
  26. +106 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/search/Search.java
  27. +28 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/search/SearchActions.java
  28. +172 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/test/FluentTest.java
  29. +68 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/wait/FluentLeniumWait.java
  30. +109 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/wait/FluentLeniumWaitBuilder.java
  31. +189 −0 fluentlenium-core/src/main/java/org/fluentlenium/core/wait/FluentWaitBuilder.java
  32. +55 −0 fluentlenium-core/src/test/java/org/integration/ActionOnListTest.java
  33. +53 −0 fluentlenium-core/src/test/java/org/integration/ActionOnListWithBddTest.java
  34. +56 −0 fluentlenium-core/src/test/java/org/integration/ActionOnSelectorTest.java
  35. +46 −0 fluentlenium-core/src/test/java/org/integration/ActionOnSelectorWithBddTest.java
  36. +78 −0 fluentlenium-core/src/test/java/org/integration/FluentLeniumWaitOnLabsTest.java
  37. +130 −0 fluentlenium-core/src/test/java/org/integration/FluentLeniumWaitTest.java
  38. +53 −0 fluentlenium-core/src/test/java/org/integration/FluentListParamTest.java
  39. +137 −0 fluentlenium-core/src/test/java/org/integration/FluentSelectorTest.java
  40. +37 −0 fluentlenium-core/src/test/java/org/integration/JavascriptTest.java
  41. +98 −0 fluentlenium-core/src/test/java/org/integration/PageTest.java
  42. +43 −0 fluentlenium-core/src/test/java/org/integration/ParamTest.java
  43. +63 −0 fluentlenium-core/src/test/java/org/integration/SearchTest.java
  44. +227 −0 fluentlenium-core/src/test/java/org/integration/SelectorOnLabsTest.java
  45. +61 −0 fluentlenium-core/src/test/java/org/integration/StateOnElementTest.java
  46. +31 −0 fluentlenium-core/src/test/java/org/integration/localTest/LocalFluentCase.java
  47. +49 −0 fluentlenium-core/src/test/java/org/sample/BingTest.java
  48. +33 −0 fluentlenium-core/src/test/java/org/unit/AfterTest.java
  49. +110 −0 fluentlenium-core/src/test/java/org/unit/CheckFindSelector.java
  50. +113 −0 fluentlenium-core/src/test/java/org/unit/FluentListSearch.java
  51. +184 −0 fluentlenium-core/src/test/java/org/unit/GlobalSearch.java
  52. +71 −0 fluentlenium-core/src/test/java/org/unit/GoToTest.java
  53. +84 −0 fluentlenium-core/src/test/java/org/unit/PreFilterAnalyse.java
  54. +59 −0 fluentlenium-core/src/test/java/org/unit/initialization/AnnotationInitialization.java
  55. +76 −0 fluentlenium-core/src/test/java/org/unit/initialization/BeforeInitialization.java
  56. +38 −0 fluentlenium-core/src/test/java/org/unit/initialization/ConstructorInitialization.java
  57. +12 −0 fluentlenium-core/src/test/java/org/unit/initialization/TestExternalPage.java
View
22 etc/jetty.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+
+ 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
+
+-->
+
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+
+<Configure id="Server" class="org.mortbay.jetty.Server">
+
+</Configure>
View
257 fluentlenium-core/src/main/java/org/fluentlenium/core/Fluent.java
@@ -0,0 +1,257 @@
+/**
+ * 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 org.fluentlenium.core;
+
+import org.fluentlenium.core.action.FillConstructor;
+import org.fluentlenium.core.action.FluentDefaultActions;
+import org.fluentlenium.core.domain.FluentList;
+import org.fluentlenium.core.domain.FluentWebElement;
+import org.fluentlenium.core.filter.Filter;
+import org.fluentlenium.core.search.Search;
+import org.fluentlenium.core.search.SearchActions;
+import org.fluentlenium.core.wait.FluentLeniumWait;
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.WebDriver;
+
+import java.util.List;
+
+/**
+ * Util Class which offers some shortcut to webdriver methods
+ */
+public abstract class Fluent implements SearchActions {
+ private WebDriver driver;
+ private Search search;
+ private FluentLeniumWait wait;
+
+ public Fluent(WebDriver driver) {
+ this.driver = driver;
+ this.search = new Search(driver);
+ this.wait = new FluentLeniumWait(driver,search);
+ }
+
+ public Fluent() {
+ }
+
+ protected final void setDriver(WebDriver driver) {
+ this.driver = driver;
+ this.search = new Search(driver);
+ if (driver != null) {
+ this.wait = new FluentLeniumWait(driver,search);
+ }
+ }
+
+ protected WebDriver getDriver() {
+ return driver;
+ }
+
+ public FluentLeniumWait await() {
+ return wait;
+ }
+
+
+ /**
+ * Return the title of the page
+ *
+ * @return
+ */
+ protected String title() {
+ return driver.getTitle();
+ }
+
+ /**
+ * Return the url of the page
+ *
+ * @return
+ */
+ protected String url() {
+ return driver.getCurrentUrl();
+ }
+
+ /**
+ * Return the source of the page
+ *
+ * @return
+ */
+ protected String pageSource() {
+ return driver.getPageSource();
+ }
+
+ public void executeScript(String script) {
+ ((JavascriptExecutor) driver).executeScript(script);
+ }
+
+ /**
+ * Central methods to find elements on the page. Can provide some filters. Able to use css1, css2, css3, see WebDriver restrictions
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentList $(String name, final Filter... filters) {
+ return search.find(name, filters);
+ }
+
+
+ /**
+ * Central methods a find element on the page, the number indicat the index of the desired element on the list. Can provide some filters. Able to use css1, css2, css3, see WebDriver restrictions
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentWebElement $(String name, Integer number, final Filter... filters) {
+ return search.find(name, number, filters);
+ }
+
+
+ /**
+ * return the lists corresponding to the cssSelector with it filters
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentList find(String name, final Filter... filters) {
+ return search.find(name, filters);
+ }
+
+ /**
+ * Return the elements at the numner position into the the lists corresponding to the cssSelector with it filters
+ *
+ * @param name
+ * @param number
+ * @param filters
+ * @return
+ */
+ public FluentWebElement find(String name, Integer number, final Filter... filters) {
+ return search.find(name, number, filters);
+ }
+
+ /**
+ * Return the first elements corresponding to the name and the filters
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentWebElement findFirst(String name, final Filter... filters) {
+ return search.findFirst(name, filters);
+ }
+
+ /**
+ * Construct a FillConstructor in order to allow easy fill
+ * Be careful - only the visible elements are filled
+ *
+ * @param cssSelector
+ */
+ public FillConstructor fill(String cssSelector, Filter... filters) {
+ return new FillConstructor(cssSelector, getDriver(), filters);
+ }
+
+ /**
+ * Construct a FillConstructor in order to allow easy fill
+ * Be careful - only the visible elements are filled
+ *
+ * @param list
+ */
+ public FillConstructor fill(FluentDefaultActions list, Filter... filters) {
+ return new FillConstructor(list, getDriver(), filters);
+ }
+
+ /**
+ * click all elements that are in cssSelector with its filters
+ * Be careful - only the visible elements are clicked
+ *
+ * @param cssSelector
+ */
+ public void click(String cssSelector, Filter... filters) {
+ $(cssSelector, filters).click();
+ }
+
+ /**
+ * Submit all elements that are in cssSelector with its filters
+ * Be careful - only the visible elements are cleared
+ *
+ * @param cssSelector
+ */
+ public void clear(String cssSelector, Filter... filters) {
+ $(cssSelector, filters).clear();
+ }
+
+ /**
+ * Submit all elements that are in cssSelector with its filters
+ * Be careful - only the visible elements are submitted
+ *
+ * @param cssSelector
+ */
+ public void submit(String cssSelector, Filter... filters) {
+ $(cssSelector, filters).submit();
+ }
+
+ /**
+ * get a list all elements that are in cssSelector with its filters
+ * Be careful - only the visible elements are submitted
+ * //TODO UTILITY ? Deprecated ?
+ *
+ * @param cssSelector
+ */
+ public List<String> text(String cssSelector, Filter... filters) {
+ return $(cssSelector, filters).getTexts();
+ }
+
+ /**
+ * Value all elements that are in cssSelector with its filters
+ * Be careful - only the visible elements are returned
+ * //TODO UTILITY ? Deprecated ?
+ *
+ * @param cssSelector
+ */
+ public List<String> value(String cssSelector, Filter... filters) {
+ return $(cssSelector, filters).getValues();
+ }
+
+
+ /**
+ * click all elements that are in the list
+ * Be careful - only the visible elements are clicked
+ *
+ * @param fluentObject
+ */
+ public void click(FluentDefaultActions fluentObject) {
+ fluentObject.click();
+ }
+
+ /**
+ * Submit all elements that are in the list
+ * Be careful - only the visible elements are cleared
+ *
+ * @param fluentObject
+ */
+ public void clear(FluentDefaultActions fluentObject) {
+ fluentObject.clear();
+ }
+
+ /**
+ * Submit all elements that are in the list
+ * Be careful - only the visible elements are submitted
+ *
+ * @param fluentObject
+ */
+ public void submit(FluentDefaultActions fluentObject) {
+ fluentObject.submit();
+ }
+
+
+}
View
64 fluentlenium-core/src/main/java/org/fluentlenium/core/FluentPage.java
@@ -0,0 +1,64 @@
+/**
+ * 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 org.fluentlenium.core;
+
+import org.openqa.selenium.WebDriver;
+
+/**
+ * Use the Page Object Pattern to have more resilient tests.
+ */
+public abstract class FluentPage extends Fluent {
+
+ public FluentPage() {
+ super();
+ }
+
+ public FluentPage(WebDriver driver) {
+ super(driver);
+ }
+
+ /**
+ * Url of the Page
+ *
+ * @return
+ */
+ public String getUrl() {
+ return null;
+ }
+
+ /**
+ * Should check if the navigator is on correct page.
+ * <p/>
+ * For example :
+ * assertThat(title()).isEqualTo("Page 1");
+ * assertThat("#reallyImportantField").hasSize(1);
+ */
+ public void isAt() {
+ }
+
+ /**
+ * Go to the url defined in the page
+ */
+ public final void go() {
+ if (getUrl() == null) {
+ throw new IllegalArgumentException("No URL have been defined for this page");
+ }
+ getDriver().get(getUrl());
+ }
+
+
+
+
+}
View
49 fluentlenium-core/src/main/java/org/fluentlenium/core/action/FillConstructor.java
@@ -0,0 +1,49 @@
+/**
+ * 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 org.fluentlenium.core.action;
+
+import org.fluentlenium.core.filter.Filter;
+import org.openqa.selenium.WebDriver;
+
+public class FillConstructor extends org.fluentlenium.core.Fluent {
+ private String cssSelector;
+ private Filter[] filters;
+ private FluentDefaultActions fluentList;
+
+ public FillConstructor(String cssSelector, WebDriver webDriver, Filter... filters) {
+ super(webDriver);
+ this.cssSelector = cssSelector;
+ this.filters = filters;
+ }
+
+ public FillConstructor(FluentDefaultActions list, WebDriver driver, Filter[] filters) {
+ super(driver);
+ this.filters = filters.clone();
+ this.fluentList = list;
+ }
+
+ /**
+ * Set the values params as text for the fluentList or search a new list with the css selector and filters and add the values param on it
+ *
+ * @param values
+ */
+ public void with(String... values) {
+ if (fluentList != null) {
+ fluentList.text(values);
+ } else {
+ $(cssSelector, filters).text(values);
+ }
+ }
+}
View
29 fluentlenium-core/src/main/java/org/fluentlenium/core/action/FluentDefaultActions.java
@@ -0,0 +1,29 @@
+/**
+ * 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 org.fluentlenium.core.action;
+
+/**
+ * All actions that can be used on the list or on a web element
+ */
+public interface FluentDefaultActions {
+ void click();
+
+ void clear();
+
+ void submit();
+
+ void text(String... text);
+
+}
View
25 fluentlenium-core/src/main/java/org/fluentlenium/core/annotation/Page.java
@@ -0,0 +1,25 @@
+/**
+ * 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 org.fluentlenium.core.annotation;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Page {
+}
View
219 fluentlenium-core/src/main/java/org/fluentlenium/core/domain/FluentList.java
@@ -0,0 +1,219 @@
+/**
+ * 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 org.fluentlenium.core.domain;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import org.fluentlenium.core.action.FluentDefaultActions;
+import org.fluentlenium.core.filter.Filter;
+import org.fluentlenium.core.search.SearchActions;
+import org.openqa.selenium.NoSuchElementException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Map the list to a FluentList in order to offers some events like click(), submit(), value() ...
+ */
+public class FluentList<E extends FluentWebElement> extends ArrayList<E> implements FluentDefaultActions, SearchActions {
+
+ public FluentList(Collection<E> listFiltered) {
+ super(listFiltered);
+ }
+
+ /**
+ * Return the first element of the list
+ * If none, return NoSuchElementException
+ *
+ * @return
+ * @throws NoSuchElementException
+ */
+ public E first() {
+ if (this.size() == 0) {
+ throw new NoSuchElementException("Element not found");
+ }
+ return this.get(0);
+ }
+
+ /**
+ * Click on all elements on the list
+ * Only the visible elements are filled
+ */
+ public void click() {
+ for (E fluentWebElement : this) {
+ if (fluentWebElement.isEnabled()) {
+ fluentWebElement.click();
+ }
+ }
+ }
+
+ /**
+ * Fill all elements on the list with the corresponding cell in the with table.
+ * Only the visible elements are filled
+ * If there is more elements on the list than in the with table, the last element of the table is repeated
+ */
+ public void text(String... with) {
+ if (with.length > 0) {
+ int id = 0;
+ String value;
+ for (E fluentWebElement : this) {
+ if (fluentWebElement.isDisplayed()) {
+ if (with.length > id) {
+ value = with[id++];
+ } else {
+ value = with[with.length - 1];
+ }
+ if (fluentWebElement.isEnabled()) {
+ fluentWebElement.clear();
+ fluentWebElement.text(value);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Clear all elements on the list
+ * Only the visible elements are filled
+ */
+ public void clear() {
+ for (E fluentWebElement : this) {
+ if (fluentWebElement.isEnabled()) {
+ fluentWebElement.clear();
+ }
+ }
+ }
+
+ /**
+ * submit on all elements on the list
+ * Only the visible elements are submitted
+ */
+ public void submit() {
+ for (E fluentWebElement : this) {
+ if (fluentWebElement.isEnabled()) {
+ fluentWebElement.submit();
+ }
+ }
+ }
+
+ /**
+ * Return the value of elements on the list
+ *
+ * @return
+ */
+ public List<String> getValues() {
+ return Lists.transform(this, new Function<E, String>() {
+ public String apply(E webElement) {
+ return webElement.getValue();
+ }
+ });
+ }
+
+ /**
+ * Return the id of elements on the list
+ *
+ * @return
+ */
+ public List<String> getIds() {
+ return Lists.transform(this, new Function<E, String>() {
+ public String apply(E webElement) {
+ return webElement.getId();
+ }
+ });
+ }
+
+ /**
+ * Return a custom attribute of elements on the list
+ *
+ * @return
+ */
+ public List<String> getAttributes(final String attribute) {
+ return Lists.transform(this, new Function<E, String>() {
+ public String apply(E webElement) {
+ return webElement.getAttribute(attribute);
+ }
+ });
+ }
+ /**
+ * Return the name of elements on the list
+ *
+ * @return
+ */
+ public List<String> getNames() {
+ return Lists.transform(this, new Function<E, String>() {
+ public String apply(E webElement) {
+ return webElement.getName();
+ }
+ });
+ }
+
+ /**
+ * Return the texts of list elements
+ *
+ * @return
+ */
+ public List<String> getTexts() {
+ return Lists.transform(this, new Function<E, String>() {
+ public String apply(E webElement) {
+ return webElement.getText();
+ }
+ });
+ }
+
+ /**
+ * find elements into the childs with the corresponding filters
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentList find(String name, Filter... filters) {
+ List<E> finds = new ArrayList<E>();
+ for (E e : this) {
+ finds.addAll(e.find(name, filters));
+ }
+ return new FluentList(finds);
+ }
+
+
+ /**
+ * find elements into the childs with the corresponding filters at the position indicated by the number
+ *
+ * @param name
+ * @param number
+ * @param filters
+ * @return
+ */
+ public E find(String name, Integer number, Filter... filters) {
+ FluentList<E> fluentList = find(name, filters);
+ if (number >= fluentList.size()) {
+ throw new NoSuchElementException("No such element with position :" + number + ". Number of elements available :" + fluentList.size());
+ }
+ return fluentList.get(number);
+ }
+
+ /**
+ * find elements into the childs with the corresponding filters at the first position
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public E findFirst(String name, Filter... filters) {
+ return find(name, 0, filters);
+ }
+}
+
View
192 fluentlenium-core/src/main/java/org/fluentlenium/core/domain/FluentWebElement.java
@@ -0,0 +1,192 @@
+/**
+ * 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 org.fluentlenium.core.domain;
+
+import org.fluentlenium.core.action.FluentDefaultActions;
+import org.fluentlenium.core.filter.Filter;
+import org.fluentlenium.core.search.Search;
+import org.fluentlenium.core.search.SearchActions;
+import org.openqa.selenium.Dimension;
+import org.openqa.selenium.WebElement;
+
+/**
+ * WebElementCustom include a Selenium WebElement. It provides a lot of shortcuts to make selenium more fluent
+ */
+public class FluentWebElement implements FluentDefaultActions, SearchActions {
+ private final WebElement webElement;
+ private final Search search;
+
+ public FluentWebElement(WebElement webElement) {
+ this.webElement = webElement;
+ this.search = new Search(webElement);
+ }
+
+ /**
+ * Click on the element
+ */
+ public void click() {
+ webElement.click();
+ }
+
+ /**
+ * Clear the element
+ */
+ public void clear() {
+ webElement.clear();
+ }
+
+ /**
+ * Submit the element
+ */
+ public void submit() {
+ webElement.submit();
+ }
+
+ /**
+ * Set the text elelent
+ *
+ * @param text
+ */
+ public void text(String... text) {
+ webElement.clear();
+ if (text.length != 0) {
+ webElement.sendKeys(text[0]);
+ }
+ }
+
+ /**
+ * return the name of the element
+ *
+ * @return
+ */
+ public String getName() {
+ return webElement.getAttribute("name");
+ }
+
+ /**
+ * return any value of custom attribute (generated=true will return "true" if getAttribute("generated") is called.
+ *
+ * @param attribute
+ * @return
+ */
+ public String getAttribute(String attribute) {
+ return webElement.getAttribute(attribute);
+ }
+
+ /**
+ * return the id of the elements
+ *
+ * @return
+ */
+ public String getId() {
+ return webElement.getAttribute("id");
+ }
+
+ /**
+ * return the text of the element
+ *
+ * @return
+ */
+ public String getText() {
+ return webElement.getText();
+ }
+
+ /**
+ * return the value of the elements
+ *
+ * @return
+ */
+ public String getValue() {
+ return webElement.getAttribute("value");
+ }
+
+ /**
+ * return true if the element is displayed, otherway return false
+ *
+ * @return
+ */
+ public boolean isDisplayed() {
+ return webElement.isDisplayed();
+ }
+
+ /**
+ * return true if the element is enabled, otherway return false
+ *
+ * @return
+ */
+ public boolean isEnabled() {
+ return webElement.isEnabled();
+ }
+
+ /**
+ * return true if the element is selected, otherway false
+ *
+ * @return
+ */
+ public boolean isSelected() {
+ return webElement.isSelected();
+ }
+
+ /**
+ * return the tag name
+ *
+ * @return
+ */
+ public String getTagName() {
+ return webElement.getTagName();
+ }
+
+ /**
+ * return the size of the elements
+ *
+ * @return
+ */
+ public Dimension getSize() {
+ return webElement.getSize();
+ }
+
+ /**
+ * find elements into the childs with the corresponding filters
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentList find(String name, Filter... filters) {
+ return search.find(name, filters);
+ }
+
+ /**
+ * find elements into the childs with the corresponding filters at the given positiokn
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentWebElement find(String name, Integer number, Filter... filters) {
+ return search.find(name, number, filters);
+ }
+
+ /**
+ * find elements into the childs with the corresponding filters at the first position
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentWebElement findFirst(String name, Filter... filters) {
+ return search.findFirst(name, filters);
+ }
+}
View
26 fluentlenium-core/src/main/java/org/fluentlenium/core/exception/ConstructionException.java
@@ -0,0 +1,26 @@
+/**
+ * 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 org.fluentlenium.core.exception;
+
+
+public class ConstructionException extends RuntimeException {
+
+ public ConstructionException(String s) {
+ super(s);
+ }
+
+ public ConstructionException(String s, Throwable t) {
+ super(s, t);
+ }
+}
View
89 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/Filter.java
@@ -0,0 +1,89 @@
+/**
+ * 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 org.fluentlenium.core.filter;
+
+import org.fluentlenium.core.filter.matcher.EqualMatcher;
+import org.fluentlenium.core.filter.matcher.Matcher;
+
+
+public class Filter {
+ private final String attribut;
+ private final Matcher matcher;
+
+ /**
+ * Construct a filter with a type and an associated value
+ *
+ * @param filterType
+ * @param value
+ */
+ public Filter(FilterType filterType, String value) {
+ this.attribut = filterType.name();
+ this.matcher = new EqualMatcher(value);
+ }
+
+ /**
+ * Construct a filter with a type and an associated matcher
+ *
+ * @param filterType
+ * @param matcher
+ */
+ public Filter(FilterType filterType, Matcher matcher) {
+ this.attribut = filterType.name();
+ this.matcher = matcher;
+ }
+
+ /**
+ * Construct a filter with on a custom attribute and an associated value
+ *
+ * @param customAttribute
+ * @param value
+ */
+ public Filter(String customAttribute, String value) {
+ this.attribut = customAttribute;
+ this.matcher = new EqualMatcher(value);
+ }
+
+
+ /**
+ * Construct a filter with on a custom attribute and an associated matcher
+ *
+ * @param customAttribute
+ * @param matcher
+ */
+ public Filter(String customAttribute, Matcher matcher) {
+ this.attribut = customAttribute;
+ this.matcher = matcher;
+ }
+
+ public String getAttribut() {
+ return attribut.toLowerCase();
+ }
+
+ public String toString() {
+ String matcherAttribute = matcher != null ? matcher.getMatcherSymbol() : "";
+ return "[" + attribut.toLowerCase() + matcherAttribute + "=\"" + matcher.getValue() + "\"]";
+ }
+
+ public Matcher getMatcher() {
+ return matcher;
+ }
+
+ public boolean isPreFilter() {
+ if ((matcher != null && matcher.isPreFilter()) && !FilterType.TEXT.name().equalsIgnoreCase(getAttribut())) {
+ return true;
+ }
+ return false;
+ }
+}
View
87 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterBuilder.java
@@ -0,0 +1,87 @@
+/**
+ * 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 org.fluentlenium.core.filter;
+
+import org.fluentlenium.core.filter.matcher.*;
+
+import java.util.regex.Pattern;
+
+
+public class FilterBuilder {
+
+ String attribute;
+
+ public FilterBuilder(String customAttribute) {
+ this.attribute = customAttribute;
+ }
+
+ public FilterBuilder(FilterType filterType) {
+ this.attribute = filterType.name();
+
+ }
+
+ public Filter equalTo(String equal) {
+ return new Filter( attribute, new EqualMatcher(equal));
+ }
+
+ public Filter contains(String equal) {
+ return new Filter( attribute, new ContainsMatcher(equal));
+ }
+
+ public Filter contains(Pattern equal) {
+ return new Filter( attribute, new ContainsMatcher(equal));
+ }
+
+ public Filter startsWith(String equal) {
+ return new Filter( attribute, new StartsWithMatcher(equal));
+ }
+
+ public Filter startsWith(Pattern equal) {
+ return new Filter( attribute, new StartsWithMatcher(equal));
+ }
+
+ public Filter endsWith(String equal) {
+ return new Filter( attribute, new EndsWithMatcher(equal));
+ }
+
+ public Filter endsWith(Pattern equal) {
+ return new Filter( attribute, new EndsWithMatcher(equal));
+ }
+
+ public Filter notContains(String equal) {
+ return new Filter( attribute, new NotContainsMatcher(equal));
+ }
+
+ public Filter notContains(Pattern equal) {
+ return new Filter( attribute, new NotContainsMatcher(equal));
+ }
+
+ public Filter notStartsWith(String equal) {
+ return new Filter( attribute, new NotStartsWithMatcher(equal));
+ }
+
+ public Filter notStartsWith(Pattern equal) {
+ return new Filter( attribute, new NotStartsWithMatcher(equal));
+ }
+
+ public Filter notEndsWith(String equal) {
+ return new Filter( attribute, new NotEndsWithMatcher(equal));
+ }
+
+ public Filter notEndsWith(Pattern equal) {
+ return new Filter( attribute, new NotEndsWithMatcher(equal));
+ }
+
+
+}
View
175 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterConstructor.java
@@ -0,0 +1,175 @@
+/**
+ * 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 org.fluentlenium.core.filter;
+
+import org.fluentlenium.core.filter.matcher.ContainsMatcher;
+import org.fluentlenium.core.filter.matcher.Matcher;
+
+
+public final class FilterConstructor {
+
+ private FilterConstructor() {
+ }
+
+ /**
+ * Create a filter by name
+ *
+ * @param name
+ * @return
+ */
+ public static Filter buildFilter(String name,FilterType type,Class matcherType) {
+ if (matcherType.equals(ContainsMatcher.class)){
+ return new Filter(FilterType.NAME, name);
+ }
+ return null;
+ }
+
+ /**
+ * Create a filter by name
+ *
+ * @param name
+ * @return
+ */
+ public static Filter withName(String name) {
+ return new Filter(FilterType.NAME, name);
+ }
+
+ /**
+ * Create a filter by id
+ *
+ * @param id
+ * @return
+ */
+ public static Filter withId(String id) {
+ return new Filter(FilterType.ID, id);
+ }
+
+
+ /**
+ * Create a filter by text
+ *
+ * @param text
+ * @return
+ */
+ public static Filter withText(String text) {
+ return new Filter(FilterType.TEXT, MatcherConstructor.equal(text));
+ }
+
+
+ /**
+ * Create a filter builder for the attribute
+ *
+ * @param attribute
+ * @return
+ */
+ public static FilterBuilder with(String attribute) {
+ return new FilterBuilder(attribute);
+ }
+
+ /**
+ * Create a filter builder for the attribute by name
+ *
+ * @param
+ * @return
+ */
+ public static FilterBuilder withName() {
+ return new FilterBuilder(FilterType.NAME);
+ }
+ /**
+ * Create a filter builder for the attribute by id
+ *
+ * @param
+ * @return
+ */
+ public static FilterBuilder withId() {
+ return new FilterBuilder(FilterType.ID);
+ }
+
+ /**
+ * Create a filter builder for the attribute by text
+ *
+ * @param
+ * @return
+ */
+ public static FilterBuilder withText() {
+ return new FilterBuilder(FilterType.TEXT);
+ }
+
+ /**
+ * Create a filter by name with matcher
+ * DEPRECATED : use withName().+convenient method
+ *
+ * @param matcher
+ * @return
+ */
+ @Deprecated
+ public static Filter withName(Matcher matcher) {
+ return new Filter(FilterType.NAME, matcher);
+ }
+
+ /**
+ * Create a filter by id
+ * DEPRECATED : use withId().+convenient method
+ *
+ * @param matcher
+ * @return
+ */
+ @Deprecated
+ public static Filter withId(Matcher matcher) {
+ return new Filter(FilterType.ID, matcher);
+ }
+
+ /**
+ * Create a filter by text
+ * DEPRECATED : use withText().+convenient method
+ *
+ * @param matcher
+ * @return
+ */
+ @Deprecated
+ public static Filter withText(Matcher matcher) {
+ return new Filter(FilterType.TEXT, matcher);
+ }
+
+ /**
+ * Create a filter by a customattribute
+ * <p/>
+ * DEPRECATED : use with(customAttribute).+convenient method
+ *
+ * @param customAttribute
+ * @param matcher
+ * @return
+ */
+ @Deprecated
+ public static Filter with(String customAttribute, Matcher matcher) {
+ return new Filter(customAttribute, matcher);
+ }
+
+ /**
+ * Create a filter by a customattribute
+ * <p/>
+ * DEPRECATED : use with(customAttribute).+convenient method
+ *
+ * @param customAttribute
+ * @param matcher
+ * @return
+ */
+ @Deprecated
+ public static Filter with(String customAttribute, String matcher) {
+ return new Filter(customAttribute, matcher);
+ }
+
+
+}
View
43 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterPredicate.java
@@ -0,0 +1,43 @@
+/**
+ * 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 org.fluentlenium.core.filter;
+
+import com.google.common.base.Predicate;
+import org.fluentlenium.core.domain.FluentWebElement;
+
+/**
+ * Filter a FluentWebElement collection to return only the elements with the same text
+ */
+public class FilterPredicate implements Predicate<FluentWebElement> {
+ private final Filter filter;
+
+ public FilterPredicate(Filter text) {
+ this.filter = text;
+ }
+
+ public boolean apply(FluentWebElement webElementCustom) {
+
+ String attribute = returnTextIfTextAttributeElseAttributeValue(webElementCustom);
+ if (filter != null && filter.getMatcher().isSatisfiedBy(attribute)) {
+ return true;
+ }
+ return false;
+ }
+
+ private String returnTextIfTextAttributeElseAttributeValue(FluentWebElement webElementCustom) {
+ return ("text".equalsIgnoreCase(filter.getAttribut())) ? webElementCustom.getText() : webElementCustom.getAttribute(filter.getAttribut());
+ }
+
+}
View
24 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/FilterType.java
@@ -0,0 +1,24 @@
+/**
+ * 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 org.fluentlenium.core.filter;
+
+/**
+ * Different integration actually supported by the framework.
+ * PreFilter are integration than are supported by WebDriver as CSS Selector
+ * PostFilter are used after the webdriver selection to integration the collection
+ */
+public enum FilterType {
+ CUSTOM, NAME, ID, TEXT;
+}
View
172 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/MatcherConstructor.java
@@ -0,0 +1,172 @@
+/**
+ * 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 org.fluentlenium.core.filter;
+
+import org.fluentlenium.core.filter.matcher.*;
+
+import java.util.regex.Pattern;
+
+
+public final class MatcherConstructor {
+
+ private MatcherConstructor() {
+ }
+
+
+ /**
+ * Create a matcher for a containing string
+ *
+ * @param matcher
+ * @return
+ */
+ public static Matcher contains(String matcher) {
+ return new ContainsMatcher(matcher);
+ }
+
+ /**
+ * Create a matcher for a containing pattern
+ *
+ * @param pattern
+ * @return
+ */
+ public static Matcher contains(Pattern pattern) {
+ return new ContainsMatcher(pattern);
+ }
+
+ /**
+ * Create a matcher for not containing a string
+ *
+ * @param matcher
+ * @return
+ */
+
+ public static Matcher notContains(String matcher) {
+ return new NotContainsMatcher(matcher);
+ }
+
+ /**
+ * Create a matcher for not containing the pattern
+ *
+ * @param pattern
+ * @return
+ */
+ public static Matcher notContains(Pattern pattern) {
+ return new NotContainsMatcher(pattern);
+ }
+
+ /**
+ * Create a matcher to equal the string matcher
+ *
+ * @param matcher
+ * @return
+ */
+ public static Matcher equal(String matcher) {
+ return new EqualMatcher(matcher);
+ }
+
+ /**
+ * Create a Pattern given a regex. The regex is compile.
+ *
+ * @param pattern
+ * @return
+ */
+ public static Pattern regex(String pattern) {
+ return Pattern.compile(pattern);
+
+ }
+
+ /**
+ * Create a matcher filtering by a string that start with the matcher
+ *
+ * @param matcher
+ * @return
+ */
+ public static Matcher startsWith(String matcher) {
+ return new StartsWithMatcher(matcher);
+ }
+
+ /**
+ * Create a matcher filtering by a string that start with the matcher
+ *
+ * @param pattern
+ * @return
+ */
+ public static Matcher startsWith(Pattern pattern) {
+ return new StartsWithMatcher(pattern);
+ }
+
+ /**
+ * Create a matcher filtering by a string that ends with the matcher
+ *
+ * @param matcher
+ * @return
+ */
+ public static Matcher endsWith(String matcher) {
+ return new EndsWithMatcher(matcher);
+ }
+
+ /**
+ * Create a matcher filtering by a string that ends with the pattern
+ *
+ * @param pattern
+ * @return
+ */
+
+ public static Matcher endsWith(Pattern pattern) {
+ return new EndsWithMatcher(pattern);
+ }
+
+ /**
+ * Create a matcher filtering by a string that not starts with the string params
+ *
+ * @param matcher
+ * @return
+ */
+ public static Matcher notStartsWith(String matcher) {
+ return new NotStartsWithMatcher(matcher);
+ }
+
+ /**
+ * Create a matcher filtering by a string that not starts with the pattern params
+ *
+ * @param pattern
+ * @return
+ */
+
+ public static Matcher notStartsWith(Pattern pattern) {
+ return new NotStartsWithMatcher(pattern);
+ }
+
+ /**
+ * Create a matcher filtering by a string that not ends with the string params
+ *
+ * @param matcher
+ * @return
+ */
+ public static Matcher notEndsWith(String matcher) {
+ return new NotEndsWithMatcher(matcher);
+ }
+
+ /**
+ * Create a matcher filtering by a string that not ends with the pattern params
+ *
+ * @param pattern
+ * @return
+ */
+ public static Matcher notEndsWith(Pattern pattern) {
+ return new NotEndsWithMatcher(pattern);
+ }
+
+}
View
107 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/CalculateService.java
@@ -0,0 +1,107 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+/**
+ * Static class that are in charge of analyzed the filter and matcher.
+ */
+public final class CalculateService {
+ private CalculateService() {
+ }
+
+ /**
+ * check if the current value contains the patternValue or the referenceValue
+ *
+ * @param patternValue
+ * @param referenceValue
+ * @param currentValue
+ * @return
+ */
+ public static boolean contains(Pattern patternValue, String referenceValue, String currentValue) {
+ if (currentValue == null) {
+ return false;
+ }
+ if (patternValue == null) {
+ return currentValue.contains(referenceValue);
+ }
+ return patternValue.matcher(currentValue).find();
+ }
+
+ /**
+ * check if the current value is equal the patternValue or the referenceValue
+ *
+ * @param patternValue
+ * @param referenceValue
+ * @param currentValue
+ * @return
+ */
+ public static boolean equal(Pattern patternValue, String referenceValue, String currentValue) {
+ if (currentValue == null) {
+ return false;
+ }
+ if (patternValue == null) {
+ return currentValue.equals(referenceValue);
+ }
+ return patternValue.matcher(currentValue).matches();
+ }
+
+ /**
+ * check if the current value starts with the patternValue or the referenceValue
+ *
+ * @param patternValue
+ * @param referenceValue
+ * @param currentValue
+ * @return
+ */
+
+ public static boolean startsWith(Pattern patternValue, String referenceValue, String currentValue) {
+ if (currentValue == null) {
+ return false;
+ }
+ if (patternValue == null) {
+ return currentValue.startsWith(referenceValue);
+ }
+ java.util.regex.Matcher m2 = patternValue.matcher(currentValue);
+ return m2.find() && 0 == m2.start();
+ }
+
+ /**
+ * check if the current value ends with the patternValue or the referenceValue
+ *
+ * @param patternValue
+ * @param referenceValue
+ * @param currentValue
+ * @return
+ */
+
+ public static boolean endsWith(Pattern patternValue, String referenceValue, String currentValue) {
+ if (currentValue == null) {
+ return false;
+ }
+ if (patternValue == null) {
+ return currentValue.endsWith(referenceValue);
+ }
+ java.util.regex.Matcher m2 = patternValue.matcher(currentValue);
+ int end = 0;
+ while (m2.find()) {
+ end = m2.end();
+ }
+ return currentValue.length() == end;
+ }
+
+}
View
42 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/ContainsMatcher.java
@@ -0,0 +1,42 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+//TODO Remove matching pattern from there
+public class ContainsMatcher extends Matcher {
+
+ public ContainsMatcher(String value) {
+ super(value);
+ }
+
+ public ContainsMatcher(Pattern value) {
+ super(value);
+ }
+
+ @Override
+ public MatcherType getMatcherType() {
+ return MatcherType.CONTAINS;
+ }
+
+ @Override
+ public boolean isSatisfiedBy(String o) {
+ return CalculateService.contains(getPattern(), getValue(), o);
+ }
+
+
+}
View
40 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/EndsWithMatcher.java
@@ -0,0 +1,40 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+public class EndsWithMatcher extends Matcher {
+
+ public EndsWithMatcher(String value) {
+ super(value);
+ }
+
+ public EndsWithMatcher(Pattern value) {
+ super(value);
+ }
+
+ @Override
+ public MatcherType getMatcherType() {
+ return MatcherType.END_WITH;
+ }
+
+ @Override
+ public boolean isSatisfiedBy(String o) {
+ return CalculateService.endsWith(getPattern(), getValue(), o);
+ }
+
+}
View
40 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/EqualMatcher.java
@@ -0,0 +1,40 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+public class EqualMatcher extends Matcher {
+
+ public EqualMatcher(String value) {
+ super(value);
+ }
+
+ public EqualMatcher(Pattern pattern) {
+ super(pattern);
+ }
+
+ @Override
+ public MatcherType getMatcherType() {
+ return MatcherType.EQUAL;
+ }
+
+ @Override
+ public boolean isSatisfiedBy(String o) {
+ return CalculateService.equal(getPattern(), getValue(), o);
+ }
+
+}
View
82 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/Matcher.java
@@ -0,0 +1,82 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+public abstract class Matcher {
+ private String value;
+ private Pattern pattern;
+
+ protected Matcher(String value) {
+ this.value = value;
+ }
+
+ protected Matcher(Pattern value) {
+ this.pattern = value;
+ }
+
+ /**
+ * return the given value
+ *
+ * @return
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Return the matcher symbol
+ *
+ * @return
+ */
+ public String getMatcherSymbol() {
+ return getMatcherType() != null ? getMatcherType().getCssRepresentations() : null;
+ }
+
+ public final boolean isPreFilter() {
+ if (pattern != null || null == getMatcherSymbol()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * return the pattern
+ *
+ * @return
+ */
+ protected Pattern getPattern() {
+ return pattern;
+ }
+
+ /**
+ * Return the matcher type
+ *
+ * @return
+ */
+ protected abstract MatcherType getMatcherType();
+
+ /**
+ * Check if the matcher is matched given the value
+ *
+ * @param value
+ * @return
+ */
+ public abstract boolean isSatisfiedBy(String value);
+
+
+}
View
39 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/MatcherType.java
@@ -0,0 +1,39 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+/**
+ * Different integration actually supported by the framework.
+ * PreFilter are integration than are supported by WebDriver as CSS Selector
+ * PostFilter are used after the webdriver selection to integration the collection
+ */
+public enum MatcherType {
+ CONTAINS("*"), START_WITH("^"), END_WITH("$"), EQUAL(""), NOT_CONTAINS(null), NOT_START_WITH(null), NOT_END_WITH(null);
+
+ private String cssRepresentations;
+
+ MatcherType(String cssRepresentations) {
+ this.cssRepresentations = cssRepresentations;
+ }
+
+ /**
+ * Return the css representations of the matcher
+ *
+ * @return
+ */
+ public String getCssRepresentations() {
+ return cssRepresentations;
+ }
+}
View
40 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/NotContainsMatcher.java
@@ -0,0 +1,40 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+public class NotContainsMatcher extends Matcher {
+
+ public NotContainsMatcher(String value) {
+ super(value);
+ }
+
+ public NotContainsMatcher(Pattern pattern) {
+ super(pattern);
+ }
+
+ @Override
+ public MatcherType getMatcherType() {
+ return MatcherType.NOT_CONTAINS;
+ }
+
+ @Override
+ public boolean isSatisfiedBy(String o) {
+ return !CalculateService.contains(getPattern(), getValue(), o);
+ }
+
+}
View
40 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/NotEndsWithMatcher.java
@@ -0,0 +1,40 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+public class NotEndsWithMatcher extends Matcher {
+
+ public NotEndsWithMatcher(String value) {
+ super(value);
+ }
+
+ public NotEndsWithMatcher(Pattern value) {
+ super(value);
+ }
+
+ @Override
+ public MatcherType getMatcherType() {
+ return MatcherType.NOT_END_WITH;
+ }
+
+ @Override
+ public boolean isSatisfiedBy(String o) {
+ return !CalculateService.endsWith(getPattern(), getValue(), o);
+ }
+
+}
View
40 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/NotStartsWithMatcher.java
@@ -0,0 +1,40 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+public class NotStartsWithMatcher extends Matcher {
+
+ public NotStartsWithMatcher(String value) {
+ super(value);
+ }
+
+ public NotStartsWithMatcher(Pattern value) {
+ super(value);
+ }
+
+ @Override
+ public MatcherType getMatcherType() {
+ return MatcherType.NOT_START_WITH;
+ }
+
+ @Override
+ public boolean isSatisfiedBy(String o) {
+ return !CalculateService.startsWith(getPattern(), getValue(), o);
+ }
+
+}
View
49 fluentlenium-core/src/main/java/org/fluentlenium/core/filter/matcher/StartsWithMatcher.java
@@ -0,0 +1,49 @@
+/**
+ * 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 org.fluentlenium.core.filter.matcher;
+
+
+import java.util.regex.Pattern;
+
+public class StartsWithMatcher extends Matcher {
+ /**
+ * Constructor using a string as a value
+ *
+ * @param value
+ */
+ public StartsWithMatcher(String value) {
+ super(value);
+ }
+
+ /**
+ * Constructor using a pattern as a value
+ *
+ * @param value
+ */
+ public StartsWithMatcher(Pattern value) {
+ super(value);
+ }
+
+ @Override
+ public MatcherType getMatcherType() {
+ return MatcherType.START_WITH;
+ }
+
+ @Override
+ public boolean isSatisfiedBy(String o) {
+ return CalculateService.startsWith(getPattern(), getValue(), o);
+ }
+
+}
View
106 fluentlenium-core/src/main/java/org/fluentlenium/core/search/Search.java
@@ -0,0 +1,106 @@
+/**
+ * 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 org.fluentlenium.core.search;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import org.fluentlenium.core.domain.FluentList;
+import org.fluentlenium.core.domain.FluentWebElement;
+import org.fluentlenium.core.filter.Filter;
+import org.fluentlenium.core.filter.FilterPredicate;
+import org.openqa.selenium.By;
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.SearchContext;
+import org.openqa.selenium.WebElement;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+
+public class Search implements SearchActions {
+ private final SearchContext searchContext;
+
+ public Search(SearchContext context) {
+ this.searchContext = context;
+ }
+
+ /**
+ * Central methods to find elements on the page. Can provide some filters. Able to use css1, css2, css3, see WebDriver restrictions
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentList find(String name, final Filter... filters) {
+ StringBuilder sb = new StringBuilder(name);
+ List<Filter> postFilterSelector = new ArrayList<Filter>();
+ if (filters != null&&filters.length>0) {
+ for (Filter selector : filters) {
+ if (selector.isPreFilter()) {
+ sb.append(selector.toString());
+ } else {
+ postFilterSelector.add(selector);
+ }
+ }
+ }
+ List<FluentWebElement> preFiltered = select(sb.toString());
+ Collection<FluentWebElement> postFiltered = preFiltered;
+ for (Filter selector : postFilterSelector) {
+ postFiltered = Collections2.filter(postFiltered, new FilterPredicate(selector));
+ }
+
+ return new FluentList(postFiltered);
+ }
+
+ private List<FluentWebElement> select(String cssSelector) {
+ return Lists.transform(searchContext.findElements(By.cssSelector(cssSelector)), new Function<WebElement, FluentWebElement>() {
+ public FluentWebElement apply(WebElement webElement) {
+ return new FluentWebElement((webElement));
+ }
+ });
+ }
+
+
+ /**
+ * Return the elements at the numner position into the the lists corresponding to the cssSelector with it filters
+ *
+ * @param name
+ * @param number
+ * @param filters
+ * @return
+ */
+ public FluentWebElement find(String name, Integer number, final Filter... filters) {
+ List<FluentWebElement> listFiltered = find(name, filters);
+ if (number >= listFiltered.size()) {
+ throw new NoSuchElementException("No such element with position :" + number + ". Number of elements available :" + listFiltered.size());
+ }
+ return listFiltered.get(number);
+ }
+
+ /**
+ * Return the first elements corresponding to the name and the filters
+ *
+ * @param name
+ * @param filters
+ * @return
+ */
+ public FluentWebElement findFirst(String name, final Filter... filters) {
+ FluentList fluentList = find(name, filters);
+ return fluentList.first();
+ }
+
+}
View
28 fluentlenium-core/src/main/java/org/fluentlenium/core/search/SearchActions.java
@@ -0,0 +1,28 @@
+/**
+ * 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 org.fluentlenium.core.search;
+
+import org.fluentlenium.core.domain.FluentList;
+import org.fluentlenium.core.domain.FluentWebElement;
+import org.fluentlenium.core.filter.Filter;
+
+
+public interface SearchActions {
+ FluentList find(String name, Filter... filters);
+
+ FluentWebElement find(String name, Integer number, Filter... filters);
+
+ FluentWebElement findFirst(String name, Filter... filters);
+}
View
172 fluentlenium-core/src/main/java/org/fluentlenium/core/test/FluentTest.java
@@ -0,0 +1,172 @@
+/**
+ * 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 org.fluentlenium.core.test;
+
+import org.fluentlenium.core.Fluent;
+import org.fluentlenium.core.FluentPage;
+import org.fluentlenium.core.annotation.Page;
+import org.fluentlenium.core.domain.FluentWebElement;
+import org.fluentlenium.core.exception.ConstructionException;
+import org.junit.After;
+import org.junit.Before;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.firefox.FirefoxDriver;
+import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
+import org.openqa.selenium.support.pagefactory.ElementLocator;
+import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
+import org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import java.lang.reflect.*;
+
+/**
+ * All Junit Test should extends this class. It provides default parameters.
+ */
+public abstract class FluentTest extends Fluent {
+ @Before
+ public final void beforeConstructTest() {
+ this.setDriver(getDefaultDriver());
+ Class cls = null;
+ try {
+ cls = Class.forName(this.getClass().getName());
+ for (Field field : cls.getDeclaredFields()) {
+ if (field.isAnnotationPresent(Page.class)) {
+ field.setAccessible(true);
+ Class clsField = field.getType();
+ cls = Class.forName(clsField.getName());
+ Object page = initClass(cls);
+ field.set(this, page);
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ throw new ConstructionException("Class " + (cls != null ? cls.getName() : " null") + "not found", e);
+ } catch (IllegalAccessException e) {
+ throw new ConstructionException("IllegalAccessException on class " + (cls != null ? cls.getName() : " null"), e);
+ }
+ }
+
+ public FluentTest() {
+ super();
+ }
+
+ public <T extends FluentPage> T createPage(Class<T> classOfPage) {
+ return initClass(classOfPage);
+ }
+
+ private <T extends FluentPage> T initClass(Class<T> cls) {
+ T page = null;
+ try {
+ Constructor construct = cls.getDeclaredConstructor();
+ construct.setAccessible(true);
+ page = (T) construct.newInstance();
+ Class parent = Class.forName(Fluent.class.getName());
+ Method m = parent.getDeclaredMethod("setDriver", WebDriver.class);
+ m.setAccessible(true);
+ m.invoke(page, getDriver());
+
+ //init fields with default proxies
+ Field[] fields = cls.getDeclaredFields();
+ for (Field fieldFromPage : fields) {
+ if (!FluentWebElement.class.isAssignableFrom(fieldFromPage.getType())) {
+ continue;
+ }
+ fieldFromPage.setAccessible(true);
+ proxyElement(new DefaultElementLocatorFactory(getDriver()), page, fieldFromPage);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new ConstructionException("Class " + (cls != null ? cls.getName() : " null") + "not found", e);
+ } catch (IllegalAccessException e) {
+ throw new ConstructionException("IllegalAccessException on class " + (cls != null ? cls.getName() : " null"), e);
+ } catch (NoSuchMethodException e) {
+ throw new ConstructionException("No constructor found on class " + (cls != null ? cls.getName() : " null"), e);
+ } catch (InstantiationException e) {
+ throw new ConstructionException("Unable to instantiate " + (cls != null ? cls.getName() : " null"), e);
+ } catch (InvocationTargetException e) {
+ throw new ConstructionException("Cannot invoke method setDriver on " + (cls != null ? cls.getName() : " null"), e);
+ }
+ return page;
+ }
+
+ /**
+ * Override this method to change the driver
+ *
+ * @return
+ */
+ public WebDriver getDefaultDriver() {
+ return new FirefoxDriver();
+ }
+
+ public WebDriverWait getDefaultWait() {
+ return new WebDriverWait(getDefaultDriver(), 5);
+ }
+
+ /**
+ * Open the url page
+ *
+ * @param url
+ */
+ public void goTo(String url) {
+ if (url == null) {
+ throw new IllegalArgumentException("Url is mandatory");
+ }
+ getDriver().get(url);
+ }
+
+ /**
+ * Go To the page
+ *
+ * @param page
+ */
+ public static void goTo(FluentPage page) {
+ if (page == null) {
+ throw new IllegalArgumentException("Page is mandatory");
+ }
+ page.go();
+ }
+
+ public static void assertAt(FluentPage fluent) {
+ fluent.isAt();
+ }
+
+
+
+
+ @After
+ public void after() {
+ if (getDriver() != null) {
+ getDriver().quit();
+ }
+ }
+
+ private static void proxyElement(ElementLocatorFactory factory, Object page, Field field) {
+ ElementLocator locator = factory.createLocator(field);
+ if (locator == null) {
+ return;
+ }
+
+ InvocationHandler handler = new LocatingElementHandler(locator);
+ WebElement proxy = (WebElement) Proxy.newProxyInstance(
+ page.getClass().getClassLoader(), new Class[]{WebElement.class}, handler);
+ try {
+ field.setAccessible(true);
+ field.set(page, new FluentWebElement(proxy));
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+}
View
68 fluentlenium-core/src/main/java/org/fluentlenium/core/wait/FluentLeniumWait.java
@@ -0,0 +1,68 @@
+package org.fluentlenium.core.wait;
+
+
+import org.fluentlenium.core.search.Search;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.ui.FluentWait;
+
+public class FluentLeniumWait<T> implements org.openqa.selenium.support.ui.Wait<T> {
+
+ private FluentWait wait;