0
# Utilities and Helpers
1
2
The utilities package provides specialized helpers for common web interactions including dropdown selections, color handling, thread safety, and advanced element location strategies. These utilities simplify complex operations and provide additional safety and convenience features.
3
4
## Select Class for Dropdowns
5
6
```java { .api }
7
public class Select implements ISelect, WrapsElement {
8
/**
9
* Create Select helper for HTML select element
10
* @throws UnexpectedTagNameException if element is not a SELECT tag
11
*/
12
public Select(WebElement element);
13
14
/**
15
* Get the wrapped select element
16
*/
17
public WebElement getWrappedElement();
18
19
/**
20
* Check if this select element supports multiple selections
21
*/
22
public boolean isMultiple();
23
24
/**
25
* Get all option elements in the select
26
*/
27
public List<WebElement> getOptions();
28
29
/**
30
* Get all currently selected options
31
*/
32
public List<WebElement> getAllSelectedOptions();
33
34
/**
35
* Get the first selected option (or only selected option for single-select)
36
*/
37
public WebElement getFirstSelectedOption();
38
39
/**
40
* Select option by visible text
41
*/
42
public void selectByVisibleText(String text);
43
44
/**
45
* Select option by index (0-based)
46
*/
47
public void selectByIndex(int index);
48
49
/**
50
* Select option by value attribute
51
*/
52
public void selectByValue(String value);
53
54
/**
55
* Deselect all options (multi-select only)
56
* @throws UnsupportedOperationException if not multi-select
57
*/
58
public void deselectAll();
59
60
/**
61
* Deselect option by value (multi-select only)
62
*/
63
public void deselectByValue(String value);
64
65
/**
66
* Deselect option by index (multi-select only)
67
*/
68
public void deselectByIndex(int index);
69
70
/**
71
* Deselect option by visible text (multi-select only)
72
*/
73
public void deselectByVisibleText(String text);
74
}
75
```
76
77
### ISelect Interface
78
79
```java { .api }
80
public interface ISelect {
81
boolean isMultiple();
82
List<WebElement> getOptions();
83
List<WebElement> getAllSelectedOptions();
84
WebElement getFirstSelectedOption();
85
void selectByVisibleText(String text);
86
void selectByIndex(int index);
87
void selectByValue(String value);
88
void deselectAll();
89
void deselectByValue(String value);
90
void deselectByIndex(int index);
91
void deselectByVisibleText(String text);
92
}
93
```
94
95
### Select Usage Examples
96
97
```java
98
import org.openqa.selenium.support.ui.Select;
99
100
// Find select element and create Select helper
101
WebElement selectElement = driver.findElement(By.id("country"));
102
Select select = new Select(selectElement);
103
104
// Check if multiple selection is supported
105
if (select.isMultiple()) {
106
System.out.println("Multi-select dropdown");
107
} else {
108
System.out.println("Single-select dropdown");
109
}
110
111
// Select by visible text
112
select.selectByVisibleText("United States");
113
114
// Select by value attribute
115
select.selectByValue("US");
116
117
// Select by index (0-based)
118
select.selectByIndex(2);
119
120
// Get all options
121
List<WebElement> options = select.getOptions();
122
for (WebElement option : options) {
123
System.out.println("Option: " + option.getText() +
124
" (value=" + option.getAttribute("value") + ")");
125
}
126
127
// Get selected options
128
List<WebElement> selected = select.getAllSelectedOptions();
129
System.out.println("Selected options count: " + selected.size());
130
131
// For multi-select dropdowns
132
if (select.isMultiple()) {
133
// Select multiple options
134
select.selectByVisibleText("Option 1");
135
select.selectByVisibleText("Option 2");
136
137
// Deselect specific options
138
select.deselectByVisibleText("Option 1");
139
140
// Deselect all options
141
select.deselectAll();
142
}
143
```
144
145
## ThreadGuard Class
146
147
The ThreadGuard provides thread-safety verification for WebDriver instances, ensuring that WebDriver operations are only performed from the thread that created the driver instance.
148
149
```java { .api }
150
public class ThreadGuard {
151
/**
152
* Wraps a WebDriver instance with thread-safety protection
153
* @param actualWebDriver The WebDriver to protect
154
* @return Protected WebDriver proxy that throws exception on cross-thread access
155
*/
156
public static WebDriver protect(WebDriver actualWebDriver);
157
}
158
```
159
160
### ThreadGuard Usage Examples
161
162
```java
163
import org.openqa.selenium.WebDriver;
164
import org.openqa.selenium.chrome.ChromeDriver;
165
import org.openqa.selenium.support.ThreadGuard;
166
167
// Protect WebDriver instance for multithreaded usage
168
WebDriver driver = ThreadGuard.protect(new ChromeDriver());
169
170
// This will work fine from the same thread
171
driver.get("https://example.com");
172
173
// Attempting to use from different thread will throw WebDriverException
174
// "Thread safety error; this instance of WebDriver was constructed on thread..."
175
```
176
177
## LoadableComponent Classes
178
179
Provides abstractions for page objects and components that can be loaded, with automatic loading verification and timeout handling.
180
181
```java { .api }
182
public abstract class LoadableComponent<T extends LoadableComponent<T>> {
183
/**
184
* Ensure that the component is currently loaded
185
* @return The component instance
186
* @throws Error when the component cannot be loaded
187
*/
188
public T get();
189
190
/**
191
* Override to check if the component is loaded
192
* @throws Error if not loaded
193
*/
194
protected abstract void isLoaded() throws Error;
195
196
/**
197
* Override to perform loading actions
198
*/
199
protected abstract void load();
200
}
201
202
public abstract class SlowLoadableComponent<T extends LoadableComponent<T>>
203
extends LoadableComponent<T> {
204
/**
205
* Create component with timeout for loading
206
* @param clock Clock for timing
207
* @param timeOutInSeconds Maximum time to wait for loading
208
*/
209
public SlowLoadableComponent(Clock clock, int timeOutInSeconds);
210
211
/**
212
* Get component, waiting up to timeout for it to load
213
*/
214
@Override
215
public T get();
216
}
217
```
218
219
### LoadableComponent Usage Examples
220
221
```java
222
import org.openqa.selenium.support.ui.LoadableComponent;
223
224
public class LoginPage extends LoadableComponent<LoginPage> {
225
private WebDriver driver;
226
227
public LoginPage(WebDriver driver) {
228
this.driver = driver;
229
}
230
231
@Override
232
protected void load() {
233
driver.get("/login");
234
}
235
236
@Override
237
protected void isLoaded() throws Error {
238
if (!driver.getCurrentUrl().contains("/login")) {
239
throw new Error("Login page not loaded");
240
}
241
}
242
243
public void login(String user, String pass) {
244
// Will automatically load if not already loaded
245
get();
246
// ... login logic
247
}
248
}
249
```
250
251
## Color Utilities
252
253
### Color Class
254
255
```java { .api }
256
public class Color {
257
/**
258
* Create Color with RGB values and alpha
259
* @param red Red component (0-255)
260
* @param green Green component (0-255)
261
* @param blue Blue component (0-255)
262
* @param alpha Alpha channel (0.0-1.0)
263
*/
264
public Color(int red, int green, int blue, double alpha);
265
266
/**
267
* Parse color from string in various formats:
268
* - Hex: #ffffff, #fff
269
* - RGB: rgb(255, 255, 255)
270
* - RGBA: rgba(255, 255, 255, 1.0)
271
* - HSL: hsl(0, 100%, 50%)
272
* - Named colors: red, blue, etc.
273
*/
274
public static Color fromString(String value);
275
276
/**
277
* Set opacity/alpha channel
278
*/
279
public void setOpacity(double alpha);
280
281
/**
282
* Convert to CSS rgb() format
283
*/
284
public String asRgb();
285
286
/**
287
* Convert to CSS rgba() format
288
*/
289
public String asRgba();
290
291
/**
292
* Convert to hex format (#rrggbb)
293
*/
294
public String asHex();
295
296
/**
297
* Convert to Java AWT Color
298
*/
299
public java.awt.Color getColor();
300
301
public String toString();
302
public boolean equals(Object other);
303
public int hashCode();
304
}
305
```
306
307
### Colors Enum
308
309
```java { .api }
310
public enum Colors {
311
TRANSPARENT, ALICEBLUE, ANTIQUEWHITE, AQUA, AQUAMARINE, AZURE, BEIGE,
312
BISQUE, BLACK, BLANCHEDALMOND, BLUE, BLUEVIOLET, BROWN, BURLYWOOD,
313
CADETBLUE, CHARTREUSE, CHOCOLATE, CORAL, CORNFLOWERBLUE, CORNSILK,
314
CRIMSON, CYAN, DARKBLUE, DARKCYAN, DARKGOLDENROD, DARKGRAY, DARKGREEN,
315
DARKGREY, DARKKHAKI, DARKMAGENTA, DARKOLIVEGREEN, DARKORANGE, DARKORCHID,
316
DARKRED, DARKSALMON, DARKSEAGREEN, DARKSLATEBLUE, DARKSLATEGRAY,
317
DARKSLATEGREY, DARKTURQUOISE, DARKVIOLET, DEEPPINK, DEEPSKYBLUE,
318
DIMGRAY, DIMGREY, DODGERBLUE, FIREBRICK, FLORALWHITE, FORESTGREEN,
319
FUCHSIA, GAINSBORO, GHOSTWHITE, GOLD, GOLDENROD, GRAY, GREY, GREEN,
320
GREENYELLOW, HONEYDEW, HOTPINK, INDIANRED, INDIGO, IVORY, KHAKI,
321
LAVENDER, LAVENDERBLUSH, LAWNGREEN, LEMONCHIFFON, LIGHTBLUE, LIGHTCORAL,
322
LIGHTCYAN, LIGHTGOLDENRODYELLOW, LIGHTGRAY, LIGHTGREEN, LIGHTGREY,
323
LIGHTPINK, LIGHTSALMON, LIGHTSEAGREEN, LIGHTSKYBLUE, LIGHTSLATEGRAY,
324
LIGHTSLATEGREY, LIGHTSTEELBLUE, LIGHTYELLOW, LIME, LIMEGREEN, LINEN,
325
MAGENTA, MAROON, MEDIUMAQUAMARINE, MEDIUMBLUE, MEDIUMORCHID, MEDIUMPURPLE,
326
MEDIUMSEAGREEN, MEDIUMSLATEBLUE, MEDIUMSPRINGGREEN, MEDIUMTURQUOISE,
327
MEDIUMVIOLETRED, MIDNIGHTBLUE, MINTCREAM, MISTYROSE, MOCCASIN,
328
NAVAJOWHITE, NAVY, OLDLACE, OLIVE, OLIVEDRAB, ORANGE, ORANGERED,
329
ORCHID, PALEGOLDENROD, PALEGREEN, PALETURQUOISE, PALEVIOLETRED,
330
PAPAYAWHIP, PEACHPUFF, PERU, PINK, PLUM, POWDERBLUE, PURPLE,
331
REBECCAPURPLE, RED, ROSYBROWN, ROYALBLUE, SADDLEBROWN, SALMON,
332
SANDYBROWN, SEAGREEN, SEASHELL, SIENNA, SILVER, SKYBLUE, SLATEBLUE,
333
SLATEGRAY, SLATEGREY, SNOW, SPRINGGREEN, STEELBLUE, TAN, TEAL,
334
THISTLE, TOMATO, TURQUOISE, VIOLET, WHEAT, WHITE, WHITESMOKE,
335
YELLOW, YELLOWGREEN;
336
337
/**
338
* Get Color instance for this color constant
339
*/
340
public Color getColorValue();
341
}
342
```
343
344
### Color Usage Examples
345
346
```java
347
import org.openqa.selenium.support.Color;
348
import org.openqa.selenium.support.Colors;
349
350
// Parse colors from various formats
351
Color color1 = Color.fromString("#ff0000"); // Hex
352
Color color2 = Color.fromString("rgb(255, 0, 0)"); // RGB
353
Color color3 = Color.fromString("rgba(255, 0, 0, 0.5)"); // RGBA
354
Color color4 = Color.fromString("red"); // Named color
355
356
// Create color programmatically
357
Color customColor = new Color(255, 128, 0, 1.0); // Orange
358
359
// Convert between formats
360
String hex = customColor.asHex(); // #ff8000
361
String rgb = customColor.asRgb(); // rgb(255, 128, 0)
362
String rgba = customColor.asRgba(); // rgba(255, 128, 0, 1)
363
364
// Use predefined color constants
365
Color blue = Colors.BLUE.getColorValue();
366
Color transparent = Colors.TRANSPARENT.getColorValue();
367
368
// Validate element colors
369
WebElement element = driver.findElement(By.id("coloredElement"));
370
String elementColor = element.getCssValue("background-color");
371
Color actualColor = Color.fromString(elementColor);
372
Color expectedColor = Colors.RED.getColorValue();
373
374
if (actualColor.equals(expectedColor)) {
375
System.out.println("Element has correct color");
376
}
377
378
// Work with transparency
379
Color semiTransparent = new Color(255, 0, 0, 0.5);
380
semiTransparent.setOpacity(0.8); // Change alpha to 0.8
381
```
382
383
## Thread Safety
384
385
### ThreadGuard
386
387
```java { .api }
388
public class ThreadGuard {
389
/**
390
* Wrap WebDriver with thread safety protection
391
* Ensures WebDriver instance is only used from the thread that created it
392
*/
393
public static WebDriver protect(WebDriver actualWebDriver);
394
}
395
```
396
397
### ThreadGuard Usage
398
399
```java
400
import org.openqa.selenium.support.ThreadGuard;
401
import org.openqa.selenium.chrome.ChromeDriver;
402
403
// Create WebDriver and protect it with ThreadGuard
404
WebDriver driver = new ChromeDriver();
405
WebDriver protectedDriver = ThreadGuard.protect(driver);
406
407
// This will work fine (same thread)
408
protectedDriver.get("https://example.com");
409
410
// This would throw an exception if called from different thread
411
// because WebDriver instances are not thread-safe
412
new Thread(() -> {
413
try {
414
protectedDriver.get("https://another-url.com"); // Will throw exception
415
} catch (Exception e) {
416
System.err.println("Thread safety violation: " + e.getMessage());
417
}
418
}).start();
419
```
420
421
## Advanced Locator Strategies
422
423
### ByIdOrName
424
425
```java { .api }
426
public class ByIdOrName extends By {
427
/**
428
* Locator that searches by id first, then by name if id not found
429
*/
430
public ByIdOrName(String idOrName);
431
432
public WebElement findElement(SearchContext context);
433
public List<WebElement> findElements(SearchContext context);
434
public String toString();
435
}
436
```
437
438
### ByIdOrName Usage
439
440
```java
441
import org.openqa.selenium.support.ByIdOrName;
442
443
// Create locator that tries id first, then name
444
By locator = new ByIdOrName("username");
445
446
// This will find element with id="username" or name="username"
447
WebElement element = driver.findElement(locator);
448
449
// Useful for forms where fields might have either id or name attributes
450
WebElement emailField = driver.findElement(new ByIdOrName("email"));
451
WebElement passwordField = driver.findElement(new ByIdOrName("password"));
452
```
453
454
## Utility Classes and Helpers
455
456
### Quotes Utility
457
458
```java { .api }
459
public class Quotes {
460
/**
461
* Escape quotes in strings for safe use in XPath expressions
462
* Handles both single and double quotes by creating concat() expressions
463
*/
464
public static String escape(String toEscape);
465
}
466
```
467
468
### Quotes Usage
469
470
```java
471
import org.openqa.selenium.support.ui.Quotes;
472
473
// Escape text for XPath usage
474
String problematicText = "It's a \"quoted\" string";
475
String escaped = Quotes.escape(problematicText);
476
477
// Use in XPath expression
478
String xpath = "//div[text()=" + escaped + "]";
479
WebElement element = driver.findElement(By.xpath(xpath));
480
481
// Example with form validation message containing quotes
482
String errorMessage = "Please enter a valid \"email address\"";
483
String escapedMessage = Quotes.escape(errorMessage);
484
By errorLocator = By.xpath("//span[@class='error' and text()=" + escapedMessage + "]");
485
```
486
487
### LoadableComponent Pattern
488
489
```java { .api }
490
public abstract class LoadableComponent<T> {
491
/**
492
* Ensure the component is loaded, loading it if necessary
493
*/
494
public T get();
495
496
/**
497
* Load the component (implement page navigation/setup)
498
*/
499
protected abstract void load();
500
501
/**
502
* Check if component is loaded (implement verification logic)
503
* @throws Error if component is not in expected state
504
*/
505
protected abstract void isLoaded() throws Error;
506
}
507
```
508
509
### SlowLoadableComponent
510
511
```java { .api }
512
public abstract class SlowLoadableComponent<T> extends LoadableComponent<T> {
513
/**
514
* Loadable component that waits for loading with timeout
515
*/
516
public SlowLoadableComponent(Clock clock, int timeOutInSeconds);
517
518
public T get();
519
520
/**
521
* Check for error conditions during loading
522
*/
523
protected void isError() throws Error;
524
525
/**
526
* Sleep duration between load checks
527
*/
528
protected long sleepFor();
529
}
530
```
531
532
### LoadableComponent Usage Example
533
534
```java
535
public class HomePage extends LoadableComponent<HomePage> {
536
private final WebDriver driver;
537
private final String url;
538
539
public HomePage(WebDriver driver, String url) {
540
this.driver = driver;
541
this.url = url;
542
}
543
544
@Override
545
protected void load() {
546
driver.get(url);
547
}
548
549
@Override
550
protected void isLoaded() throws Error {
551
String currentUrl = driver.getCurrentUrl();
552
if (!currentUrl.contains("home")) {
553
throw new Error("Not on home page. Current URL: " + currentUrl);
554
}
555
556
// Check that key elements are present
557
try {
558
driver.findElement(By.id("main-navigation"));
559
driver.findElement(By.className("welcome-message"));
560
} catch (NoSuchElementException e) {
561
throw new Error("Home page not fully loaded: " + e.getMessage());
562
}
563
}
564
565
// Page-specific methods
566
public void clickMenuItem(String menuText) {
567
WebElement menuItem = driver.findElement(
568
By.xpath("//nav[@id='main-navigation']//a[text()='" + menuText + "']")
569
);
570
menuItem.click();
571
}
572
}
573
574
// Usage
575
HomePage homePage = new HomePage(driver, "https://example.com/home");
576
homePage.get(); // Will load page if not already loaded and verify state
577
homePage.clickMenuItem("Products");
578
```
579
580
### SlowLoadableComponent Example
581
582
```java
583
public class DashboardPage extends SlowLoadableComponent<DashboardPage> {
584
private final WebDriver driver;
585
586
public DashboardPage(WebDriver driver) {
587
super(Clock.systemDefaultZone(), 30); // 30 second timeout
588
this.driver = driver;
589
}
590
591
@Override
592
protected void load() {
593
driver.get("/dashboard");
594
}
595
596
@Override
597
protected void isLoaded() throws Error {
598
// Check URL
599
if (!driver.getCurrentUrl().contains("dashboard")) {
600
throw new Error("Not on dashboard page");
601
}
602
603
// Check that dashboard content is loaded (AJAX content)
604
try {
605
WebElement dashboardContent = driver.findElement(By.id("dashboard-content"));
606
if (!dashboardContent.isDisplayed()) {
607
throw new Error("Dashboard content not visible");
608
}
609
610
// Verify data has loaded
611
List<WebElement> dataItems = driver.findElements(By.className("data-item"));
612
if (dataItems.isEmpty()) {
613
throw new Error("Dashboard data not loaded");
614
}
615
} catch (NoSuchElementException e) {
616
throw new Error("Dashboard elements not found");
617
}
618
}
619
620
@Override
621
protected void isError() throws Error {
622
// Check for error messages
623
List<WebElement> errors = driver.findElements(By.className("error-message"));
624
if (!errors.isEmpty()) {
625
throw new Error("Error loading dashboard: " + errors.get(0).getText());
626
}
627
}
628
629
@Override
630
protected long sleepFor() {
631
return 1000; // Check every second
632
}
633
}
634
```
635
636
## Exception Classes
637
638
### UnexpectedTagNameException
639
640
```java { .api }
641
public class UnexpectedTagNameException extends WebDriverException {
642
/**
643
* Exception thrown when an element has an unexpected tag name
644
*/
645
public UnexpectedTagNameException(String expectedTagName, String actualTagName);
646
}
647
```
648
649
### Exception Usage
650
651
```java
652
// This is typically thrown by Select class constructor
653
try {
654
WebElement element = driver.findElement(By.id("not-a-select"));
655
Select select = new Select(element); // May throw UnexpectedTagNameException
656
} catch (UnexpectedTagNameException e) {
657
System.err.println("Element is not a SELECT tag: " + e.getMessage());
658
}
659
```