Skip to content

Commit 1528b02

Browse files
committed
toLower and toUpper added and README improved
1 parent 782c253 commit 1528b02

File tree

3 files changed

+84
-14
lines changed

3 files changed

+84
-14
lines changed

README.md

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# FluentSelenium
22

3-
FluentSelenium is a layer on top of Selenium 2.0 (WebDriver) that adds a [fluent interface](http://martinfowler.com/bliki/FluentInterface.html) style for working with the browser. For now, it is for the Java binding to WebDriver, and works with Java versions 5, 6, 7, 8, 9, 10, 12, 12 & 13.
3+
FluentSelenium is a wrapper for Selenium 2+ (WebDriver) that adds a [fluent interface](http://martinfowler.com/bliki/FluentInterface.html) style for working with the browser. It allows you easier and faster writing of Web UI Tests. Test code using FluentSelenium is terser and more elegant.
44

55
Of many benefits, FluentSelenium will attempt to transparently get past the stale element exception business.
66

7+
FluentSelenium works with JUnit, TestNG, ScalaTest, JBehave, Cucumber for Java, or whatever JDK language you prefer. FluentSelenium works with Java (5+), Groovy, Scala, Clojure, and Kotlin.
8+
79
## Basic Use
810

9-
Regular HTML elements have Java methods that are named for them. Locators are optional, and are from WebDriver's regular set:
11+
Regular HTML elements have Java methods that are named for them. Locators are optional, and are from WebDriver's regular set (by id, by css selector, by tag name, by xpath):
1012

1113
```java
1214
WebDriver wd = new FirefoxDriver();
@@ -47,6 +49,8 @@ fwd.span(id("results").within(millis(200)).getText().shouldBe("123");
4749

4850
This will throw an exception **after** the elapsed time, if the element still hasn't appeared in the page's DOM.
4951

52+
As well as `millis(..)` and `secs(..)`, there is also `mins(..)`
53+
5054
### without()
5155

5256
The opposite of "within", the "without" capability is going to wait for something to disappear. If the element is still in the page, it will keep waiting upto a given period of time, for it to disappear:
@@ -142,26 +146,34 @@ fwd.div(id("foo")).getText().shouldNotBe("0 bars");
142146
fwd.div(id("foo")).getText().shouldContain("bar");
143147
fwd.div(id("foo")).getText().shouldNotContain("error");
144148
```
149+
150+
See hamcrest matcher support below for more string assertions.
151+
145152
#### Text Changers
146153
147-
The `getText()` method can also take one or more `TextChanger` implementations now. These can change the value of getText() before
154+
The `getText()` method can also take one or more `TextChanger` implementations. These can change the value of getText() before
148155
handing it rightwards to an assertion, like so:
149156
157+
There are supplied ones too: `multiSpaceEliminator()`, `multiCREliminator()`, `trimmer()`, `tabsToSpaces()`, `toLowerCase()`, `toUpperCase()`, `crToChars("|")`
158+
159+
Make your own too:
160+
150161
```java
151-
fwd.div(id("foo")).getText(new MyToUppperCase()).shouldBe("1 BAR");
162+
fwd.div(id("foo")).getText(new MyTextChanger()).shouldBe("1 BAR");
152163
```
153-
There are supplied ones too: `multiSpaceEliminator()`, `trimmer()`, `tabsToSpaces()` and `crToChars("|")`
154164
155-
There is also a `Concatenator` that is available for getText() where that was implicitly a findElements (plural). There is one
165+
**Concatenators**
166+
167+
There is also a `Concatenator` that is available for getText() where that was implicitly a findElements (PLURAL). There is one
156168
supplied concatenator, `delimitWithChars(..)` used like so:
157169
158170
```java
159171
fwd.buttons(class("dialog_button")).getText(delimitWithChars("|")).shouldBe("OK|CANCEL");
160172
```
161173
174+
Specifically we found TWO buttons, one with OK and one with CANCEL and we want to confirm we had both in one operation.
162175
163-
164-
#### Regex
176+
#### Regular Expressions
165177
166178
Regex is possible too, and it will ignore carriage returns (which Java pre-processes like so \n -> \\\n)
167179
@@ -173,13 +185,16 @@ fwd.div(id("formErrors")).getText().shouldNotMatch("\d errors");
173185
174186
#### Hamcrest matchers
175187
176-
Hamcrest matchers, similarly:
188+
Any Hamcrest matchers are supported:
177189
178190
```java
179-
fwd.div(id("foo")).getText().shouldMatch(IsEqual<String>("1 bar"));
180-
fwd.div(id("formErrors")).getText().shouldNotMatch(IsEqual<String>("aardvark"));
191+
// requires static import of equalTo() from Hamcrest.
192+
fwd.div(id("foo")).getText().shouldMatch(equalTo("1 bar"));
193+
fwd.div(id("formErrors")).getText().shouldNotMatch(equalTo("aardvark"));
181194
```
182195
196+
Note: shouldMatch(..) and shouldNotMatch(..) work with regexes (above) and hamcrest matchers
197+
183198
#### Within a period of time
184199
185200
As shown above, you can transparently wait for the thing to become
@@ -191,11 +206,21 @@ fwd.div(id("foo")).getText().within(secs(10)).shouldBe("1 bar");
191206
fwd.div(id("foo")).getText().without(secs(10)).shouldBe("1 bar");
192207
```
193208
194-
The assertion is retried for the advised period.
209+
Div with ID of 'small' is in the DOM, and within 5 seconds its text changes to something that starts with 'start' -
195210
196-
#### Changing text before assertions
211+
```java
212+
// requires static import of startsWith() from Hamcrest.
213+
fwd.div(id("small")).getText().within(secs(5)).shouldMatch(startsWith("start"));
214+
```
197215
198-
Sometimes FluentWebWlement TODO
216+
Div with ID of 'small' is not in the DOM initially, but within 5 seconds it is and its text starts with 'start' -
217+
218+
```java
219+
// requires static import of startsWith() from Hamcrest.
220+
fwd.div(id("small")).within(secs(5)).getText().shouldMatch(startsWith("start"));
221+
```
222+
223+
The assertion is retried for the advised period and no longer. If not found an exception is thrown
199224
200225
### Non-String Assertions
201226
@@ -232,6 +257,7 @@ WebDriver's own "By" locator mechanism is what is used. Here are examples using
232257
by = By.id("id")
233258
by = By.className("name")
234259
by = By.tagName("table")
260+
by = By.xpath("@foo = 'bar'") // XPath should always be your last choice for locating elements
235261
```
236262

237263
New class FluentBy adds a few more locators:
@@ -270,6 +296,20 @@ elems = fwd.divs(id("foo");
270296
Look at the pluralization of the methods above, and that it only makes sense if
271297
it's the last in the fluent expression.
272298

299+
# Using WebDriver and FluentWebDriver at the same time
300+
301+
Keep a hold of the `wd` instance you made as you instantiated everything and use it as you would expect.
302+
303+
```java
304+
RemoteWebDriver wd = new FirefoxDriver();
305+
FluentWebDriver fwd = new FluentWebDriver(wd);
306+
fwd.button(id("showHandOfCards")).click();
307+
File src = wd.getScreenshotAs(OutputType.FILE);
308+
FileUtils.copyFile(src, new File(pathname));
309+
```
310+
311+
As you can creenshots and any functions on the sub-classes of WebDriver are possible.
312+
273313
# Fluently matching/filtering over multiple elements
274314

275315
Use a FluentMatcher instance (which is just a predicate)

java/src/main/java/org/seleniumhq/selenium/fluent/TestableString.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,22 @@ public String chg(String text) {
5353
};
5454
}
5555

56+
public static StringChanger upperCase() {
57+
return new StringChanger() {
58+
public String chg(String text) {
59+
return text.toUpperCase();
60+
}
61+
};
62+
}
63+
64+
public static StringChanger lowerCase() {
65+
return new StringChanger() {
66+
public String chg(String text) {
67+
return text.toLowerCase();
68+
}
69+
};
70+
}
71+
5672
public static StringChanger multiSpaceEliminator() {
5773
return new StringChanger() {
5874
public String chg(String text) {

java/src/test/java/org/seleniumhq/selenium/fluent/TestableStringTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,20 @@ public void trimmerShouldTrimStrings() {
298298
assertThat(trimmer.chg(" a "), equalTo("a"));
299299
}
300300

301+
@Test
302+
public void upperCaseShouldUpperStrings() {
303+
TestableString.StringChanger upperCase = TestableString.upperCase();
304+
assertThat(upperCase.chg(" a B c "), equalTo(" A B C "));
305+
}
306+
307+
308+
@Test
309+
public void lowerCaseShouldLowerStrings() {
310+
TestableString.StringChanger lowerCase = TestableString.lowerCase();
311+
assertThat(lowerCase.chg(" a B c "), equalTo(" a b c "));
312+
}
313+
314+
301315
@Test
302316
public void testCRstoChars() {
303317
TestableString.StringChanger crToChars = TestableString.crToChars(";");

0 commit comments

Comments
 (0)