17
17
18
18
package org .openqa .selenium .support ;
19
19
20
- import org .openqa .selenium .WebDriver ;
20
+ import org .openqa .selenium .SearchContext ;
21
21
import org .openqa .selenium .support .pagefactory .DefaultElementLocatorFactory ;
22
22
import org .openqa .selenium .support .pagefactory .DefaultFieldDecorator ;
23
23
import org .openqa .selenium .support .pagefactory .ElementLocatorFactory ;
26
26
import java .lang .reflect .Constructor ;
27
27
import java .lang .reflect .Field ;
28
28
import java .lang .reflect .InvocationTargetException ;
29
+ import java .lang .reflect .Modifier ;
29
30
30
31
31
32
/**
@@ -52,30 +53,31 @@ public class PageFactory {
52
53
* which takes a WebDriver instance as its only argument or falling back on a no-arg constructor.
53
54
* An exception will be thrown if the class cannot be instantiated.
54
55
*
55
- * @param driver The driver that will be used to look up the elements
56
+ * @param context The org.openqa.selenium.SearchContext instance that will be used to
57
+ * look up the elements
56
58
* @param pageClassToProxy A class which will be initialised.
57
59
* @return An instantiated instance of the class with WebElement and List<WebElement>
58
60
* fields proxied
59
61
* @see FindBy
60
62
* @see CacheLookup
61
63
*/
62
- public static <T > T initElements (WebDriver driver , Class <T > pageClassToProxy ) {
63
- T page = instantiatePage (driver , pageClassToProxy );
64
- initElements (driver , page );
64
+ public static <T > T initElements (SearchContext context , Class <T > pageClassToProxy ) {
65
+ T page = instantiatePage (context , pageClassToProxy );
66
+ initElements (context , page );
65
67
return page ;
66
68
}
67
69
68
70
/**
69
- * As {@link org.openqa.selenium.support.PageFactory#initElements(org.openqa.selenium.WebDriver ,
71
+ * As {@link org.openqa.selenium.support.PageFactory#initElements(org.openqa.selenium.SearchContext ,
70
72
* Class)} but will only replace the fields of an already instantiated Page Object.
71
73
*
72
- * @param driver The driver that will be used to look up the elements
74
+ * @param context The org.openqa.selenium.SearchContext instance that will be used to look up the elements
73
75
* @param page The object with WebElement and List<WebElement> fields that
74
76
* should be proxied.
75
77
*/
76
- public static void initElements (WebDriver driver , Object page ) {
77
- final WebDriver driverRef = driver ;
78
- initElements (new DefaultElementLocatorFactory (driverRef ), page );
78
+ public static void initElements (SearchContext context , Object page ) {
79
+ final SearchContext searchContextRef = context ;
80
+ initElements (new DefaultElementLocatorFactory (searchContextRef ), page );
79
81
}
80
82
81
83
/**
@@ -109,6 +111,10 @@ public static void initElements(FieldDecorator decorator, Object page) {
109
111
private static void proxyFields (FieldDecorator decorator , Object page , Class <?> proxyIn ) {
110
112
Field [] fields = proxyIn .getDeclaredFields ();
111
113
for (Field field : fields ) {
114
+ int modifiers = field .getModifiers ();
115
+ if (Modifier .isFinal (modifiers ) || Modifier .isStatic (modifiers ))
116
+ continue ;
117
+
112
118
Object value = decorator .decorate (page .getClass ().getClassLoader (), field );
113
119
if (value != null ) {
114
120
try {
@@ -121,14 +127,24 @@ private static void proxyFields(FieldDecorator decorator, Object page, Class<?>
121
127
}
122
128
}
123
129
124
- private static <T > T instantiatePage (WebDriver driver , Class <T > pageClassToProxy ) {
130
+ @ SuppressWarnings ("unchecked" )
131
+ private static <T > T instantiatePage (SearchContext context , Class <T > pageClassToProxy ) {
125
132
try {
126
- try {
127
- Constructor <T > constructor = pageClassToProxy .getConstructor (WebDriver .class );
128
- return constructor .newInstance (driver );
129
- } catch (NoSuchMethodException e ) {
130
- return pageClassToProxy .newInstance ();
133
+ Constructor <?>[] availableConstructors = pageClassToProxy .getDeclaredConstructors ();
134
+ for (Constructor <?> c : availableConstructors ){
135
+
136
+ Class <?>[] parameterTypes = c .getParameterTypes ();
137
+ if (parameterTypes .length != 1 )
138
+ continue ;
139
+
140
+ Class <?> parameterClazz = parameterTypes [0 ];
141
+ if (!parameterClazz .isAssignableFrom (context .getClass ()))
142
+ continue ;
143
+ c .setAccessible (true );
144
+ return (T ) c .newInstance (context );
131
145
}
146
+
147
+ return pageClassToProxy .newInstance ();
132
148
} catch (InstantiationException e ) {
133
149
throw new RuntimeException (e );
134
150
} catch (IllegalAccessException e ) {
0 commit comments