Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Commit 3a94425

Browse files
committed
Changed @must to @PostConstructMustBe and replaced enumeration with class reference in order to be more extendable
1 parent 89d6704 commit 3a94425

File tree

15 files changed

+130
-160
lines changed

15 files changed

+130
-160
lines changed

documentation/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
- [@Cached](chapters/annotation-cached.md)
1515
- [@IdentifyUsing](chapters/annotation-identify-using.md)
1616
- [@Mark](chapters/annotation-mark.md)
17-
- [@Must](chapters/annotation-must.md)
1817
- [@Named](chapters/annotation-named.md)
1918
- [@PostConstruct](chapters/annotation-post-construct.md)
20-
- [@Wait](chapters/annotation-wait-until.md)
19+
- [@PostConstructMustBe](chapters/annotation-post-construct-must-be.md)
20+
- [@WaitUntil](chapters/annotation-wait-until.md)
2121
- Utility Classes
2222
- [Conditions](chapters/conditions.md)
2323
- [ByProducers](chapters/by-producers.md)

documentation/chapters/annotation-must.md renamed to documentation/chapters/annotation-post-construct-must-be.md

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
11
[Home](../README.md)
22

3-
# @Must
3+
# @PostConstructMustBe
44
This annotation can be added to `@IdentifyUsing` annotated methods of `Page` or `PageFragment` subclasses.
55
Every annotated method will be invoked after an instance of this subclass was initialized and the condition provided by
66
the annotation will be checked. This mechanism is intended to be used in order to prevent unnecessary `@PostConstruct`
77
methods to check basic conditions of parts of the page / fragment. As with `@PostConstruct`, the order in which these
88
methods are invoked / checked is not deterministic!
99

10-
> Collection and Streams are currently NOT supported!
11-
12-
**The following conditions are available:**
10+
It is important to note that not all Predicate classes will work with this annotation.
11+
The mechanism with which the predicate is evaluated will initialize the given class via reflection
12+
and needs a default constructor to work!
1313

14-
- `VISIBLE`: The fragment is displayed on the current page.
15-
- `PRESENT`: The fragment is present in the current page's DOM.
16-
- `PRESENT_AND_VISIBLE`: The fragment is present in the current page's DOM and is displayed.
17-
- `ENABLED`: The fragment is enabled / not disabled.
18-
- `EDITABLE`: The fragment is enabled and not 'read-only'
19-
- `INTERACTABLE`: The fragment is visible and editable.
14+
> Collection and Streams are currently NOT supported!
2015
2116
**Example for page:**
2217
```java
2318
public interface FooPage extends Page {
2419

25-
@Must(Be.VISIBLE)
20+
@PostConstructMustBe(Visible.class)
2621
@IdentifyUsing("#foo")
2722
FooWidget widget();
2823

@@ -35,11 +30,11 @@ public interface FooPage extends Page {
3530
```java
3631
public interface FooWidget extends PageFragment {
3732

38-
@Must(Be.VISIBLE)
33+
@PostConstructMustBe(Visible.class)
3934
@IdentifyUsing("#one")
4035
TextField fieldOne();
4136

42-
@Must(Be.VISIBLE)
37+
@PostConstructMustBe(Visible.class)
4338
@IdentifyUsing("#two")
4439
TextField fieldTwo();
4540

@@ -50,17 +45,17 @@ public interface FooWidget extends PageFragment {
5045

5146
## Combination with @WaitUntil
5247

53-
The `@Must` annotation can be used in combination with `WaitUntil`. This is especially useful in AJAX heavy applications
54-
where a fragment might be created with a short delay.
48+
The `@PostConstructMustBe` annotation can be used in combination with `WaitUntil`. This is especially useful in AJAX heavy
49+
applications where a fragment might be created with a short delay.
5550

5651
**Example:**
5752
In this example the `widget` is checked as soon as `BarPage` is initialized. But `WaitUntil` will be triggered when invoking
5853
the method assuring that the widget is present before checking if it is visible.
5954
```java
6055
public interface BarPage extends Page {
6156

62-
@Must(Be.VISIBLE)
63-
WaitUntil(Present.class)
57+
@PostConstructMustBe(Visible.class)
58+
@WaitUntil(Present.class)
6459
@IdentifyUsing("#bar")
6560
BarWidget widget();
6661

documentation/chapters/annotation-post-construct.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ The order in which multiple annotated methods are invoked is not deterministic.
1010
1111
Since these methods are invoked using reflection, it is not possible to have method arguments!
1212

13-
As an alternative for `@PostConstruct` the `@Must` annotation can be used on page fragment returning methods.
14-
For more about that see [@Must](annotation-must.md).
13+
As an alternative for `@PostConstruct` the `@PostConstructMustBe` annotation can be used on page fragment returning methods.
14+
For more about that see [@PostConstructMustBe](chapters/annotation-post-construct-must-be.md).
1515

1616
**Example for page:**
1717
```java
@@ -55,4 +55,4 @@ public interface FooWidget extends PageFragment {
5555

5656
- [Pages](page.md)
5757
- [Page Fragments](page-fragment.md)
58-
- [@Must](annotation-must.md)
58+
- [@PostConstructMustBe](chapters/annotation-post-construct-must-be.md)

documentation/chapters/page-fragment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ These annotations can be used within a `PageFragment`.
9393
- [@Cached](annotation-cached.md)
9494
- [@IdentifyUsing](annotation-identify-using.md)
9595
- [@Mark](annotation-mark.md)
96-
- [@Must](annotation-must.md)
9796
- [@Named](annotation-named.md)
9897
- [@PostConstruct](annotation-post-construct.md)
98+
- [@PostConstructMustBe](chapters/annotation-post-construct-must-be.md)
9999
- [@WaitUntil](annotation-wait-until.md)
100100

101101
# Linked Documentation

documentation/chapters/page.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ These annotations can be used within a `Page`.
9595
- [@Action](annotation-action.md)
9696
- [@Cached](annotation-cached.md)
9797
- [@IdentifyUsing](annotation-identify-using.md)
98-
- [@Must](annotation-must.md)
9998
- [@Named](annotation-named.md)
10099
- [@PostConstruct](annotation-post-construct.md)
100+
- [@PostConstructMustBe](chapters/annotation-post-construct-must-be.md)
101101
- [@WaitUntil](annotation-wait-until.md)
102102

103103
# Anatomy of a Page

webtester-core/src/main/java/info/novatec/testit/webtester/internal/must/MustChecker.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@
1111

1212
import info.novatec.testit.webtester.internal.exceptions.IllegalSignatureException;
1313
import info.novatec.testit.webtester.pagefragments.PageFragment;
14-
import info.novatec.testit.webtester.pagefragments.annotations.Be;
1514
import info.novatec.testit.webtester.pagefragments.annotations.IdentifyUsing;
16-
import info.novatec.testit.webtester.pagefragments.annotations.Must;
15+
import info.novatec.testit.webtester.pagefragments.annotations.PostConstructMustBe;
1716
import info.novatec.testit.webtester.pages.Page;
1817

1918

2019
public final class MustChecker {
2120

2221
private static final String ILLEGAL_SIGNATURE_MSG =
23-
"invalid @Must method declarations (returns PageFragment and has no parameters): ";
22+
"invalid @PostConstructMustBe method declarations (returns PageFragment and has no parameters): ";
2423

2524
private static Predicate<Method> isIdentificationMethod = method -> method.isAnnotationPresent(IdentifyUsing.class);
26-
private static Predicate<Method> isMustMethod = method -> method.isAnnotationPresent(Must.class);
25+
private static Predicate<Method> isMustMethod = method -> method.isAnnotationPresent(PostConstructMustBe.class);
2726
private static Predicate<Method> isRelevantMethod = isIdentificationMethod.and(isMustMethod);
2827
private static Predicate<Method> returnsPageFragment =
2928
method -> PageFragment.class.isAssignableFrom(method.getReturnType());
@@ -76,13 +75,13 @@ private static void assertThatAllMethodsHaveValidSignature(List<Method> mustMeth
7675

7776
private static void invoke(Method method, Object object) {
7877
try {
79-
Must annotation = method.getAnnotation(Must.class);
78+
PostConstructMustBe annotation = method.getAnnotation(PostConstructMustBe.class);
8079
PageFragment fragment = ( PageFragment ) method.invoke(object);
81-
Be condition = annotation.value();
82-
if (!condition.checkFor(fragment)) {
83-
throw new MustConditionException("condition not met for method (" + method + "): " + condition);
80+
Predicate<PageFragment> predicate = annotation.value().newInstance();
81+
if (!predicate.test(fragment)) {
82+
throw new MustConditionException("condition not met for method (" + method + "): " + predicate);
8483
}
85-
} catch (IllegalAccessException | InvocationTargetException e) {
84+
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
8685
throw new MustConditionException(e);
8786
}
8887
}

webtester-core/src/main/java/info/novatec/testit/webtester/internal/must/MustConditionException.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55

66
public class MustConditionException extends WebTesterException {
77

8-
private static final String MESSAGE = "Invocation of @Must annotated method failed! See cause for details:";
8+
private static final String MESSAGE =
9+
"Invocation of @PostConstructMustBe annotated method failed! See cause for details:";
910

1011
public MustConditionException(String message) {
1112
super(message);
1213
}
1314

1415
public MustConditionException(Throwable cause) {
15-
super(MESSAGE,cause);
16+
super(MESSAGE, cause);
1617
}
1718

1819
}

webtester-core/src/main/java/info/novatec/testit/webtester/pagefragments/annotations/Be.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

webtester-core/src/main/java/info/novatec/testit/webtester/pagefragments/annotations/Must.java

Lines changed: 0 additions & 48 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package info.novatec.testit.webtester.pagefragments.annotations;
2+
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.ElementType;
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.RetentionPolicy;
7+
import java.lang.annotation.Target;
8+
import java.util.function.Predicate;
9+
10+
import info.novatec.testit.webtester.conditions.Conditions;
11+
import info.novatec.testit.webtester.conditions.pagefragments.Disabled;
12+
import info.novatec.testit.webtester.conditions.pagefragments.Editable;
13+
import info.novatec.testit.webtester.conditions.pagefragments.Enabled;
14+
import info.novatec.testit.webtester.conditions.pagefragments.Interactable;
15+
import info.novatec.testit.webtester.conditions.pagefragments.Invisible;
16+
import info.novatec.testit.webtester.conditions.pagefragments.Present;
17+
import info.novatec.testit.webtester.conditions.pagefragments.PresentAndVisible;
18+
import info.novatec.testit.webtester.conditions.pagefragments.ReadOnly;
19+
import info.novatec.testit.webtester.conditions.pagefragments.Selected;
20+
import info.novatec.testit.webtester.conditions.pagefragments.Visible;
21+
import info.novatec.testit.webtester.pagefragments.PageFragment;
22+
import info.novatec.testit.webtester.pages.Page;
23+
24+
25+
/**
26+
* Identification methods of {@link Page pages} and {@link PageFragment page fragments} can be annotation with this
27+
* annotation. Doing so will trigger an automatic post construct check on the page / page fragment after it's
28+
* initialization. This check will take the {@link PostConstructMustBe @PostConstructMustBe's} condition and evaluate it.
29+
* <p>
30+
* <b>Important:</b> The used predicate class must provide a default constructor! Hence not all of our provided {@link
31+
* Conditions} will work. The following conditions can be used:
32+
* <ul>
33+
* <li>{@link Disabled}</li>
34+
* <li>{@link Editable}</li>
35+
* <li>{@link Enabled}</li>
36+
* <li>{@link Interactable}</li>
37+
* <li>{@link Invisible}</li>
38+
* <li>{@link Present}</li>
39+
* <li>{@link PresentAndVisible}</li>
40+
* <li>{@link ReadOnly}</li>
41+
* <li>{@link Selected}</li>
42+
* <li>{@link Visible}</li>
43+
* </ul>
44+
* <p>
45+
* <b>Example:</b>
46+
* <pre>
47+
* // this will throw an exception if the username is not visible when the page is initialized
48+
* &#64;PostConstructMustBe(Visible.class)
49+
* &#64;IdentifyUsing("#username")
50+
* TextField username();
51+
*
52+
* // in cases where fragments are created using JavaScript an additional wait can be defined in the following way:
53+
* &#64;PostConstructMustBe(Visible.class)
54+
* &#64;WaitUntil(Present.class)
55+
* &#64;IdentifyUsing("#username")
56+
* TextField username();
57+
* </pre>
58+
*
59+
* @see Predicate
60+
* @see Conditions
61+
* @since 2.0
62+
*/
63+
@Documented
64+
@Retention(RetentionPolicy.RUNTIME)
65+
@Target(ElementType.METHOD)
66+
public @interface PostConstructMustBe {
67+
68+
/**
69+
* The {@link Predicate} predicate to use for the must check.
70+
*
71+
* @return the predicate to use
72+
* @since 2.0
73+
*/
74+
Class<? extends Predicate<PageFragment>> value();
75+
76+
}

0 commit comments

Comments
 (0)