41
41
import javax .script .ScriptEngine ;
42
42
import javax .script .ScriptEngineManager ;
43
43
import javax .script .ScriptException ;
44
+ import static org .testfx .util .WaitForAsyncUtils .*;
44
45
import static javafxlibrary .utils .HelperFunctions .*;
45
- import static org . testfx . util . WaitForAsyncUtils . waitFor ;
46
+
46
47
import java .util .ResourceBundle ;
47
48
48
49
public class JavaFXLibrary extends AnnotationLibrary {
@@ -51,6 +52,66 @@ public class JavaFXLibrary extends AnnotationLibrary {
51
52
public static final String ROBOT_LIBRARY_VERSION = loadRobotLibraryVersion ();
52
53
public static final TestListener ROBOT_LIBRARY_LISTENER = new TestListener ();
53
54
55
+ static List <String > noLibraryKeywordTimeoutKeywords = new ArrayList <String >() {{
56
+ add ("launchJavafxApplication" );
57
+ add ("launchSwingApplication" );
58
+ add ("launchSwingApplicationInSeparateThread" );
59
+ add ("closeJavafxApplication" );
60
+ add ("closeSwingApplication" );
61
+ add ("waitForEventsInFxApplicationThread" );
62
+ add ("waitUntilElementDoesNotExists" );
63
+ add ("waitUntilElementExists" );
64
+ add ("waitUntilNodeIsEnabled" );
65
+ add ("waitUntilNodeIsNotEnabled" );
66
+ add ("waitUntilNodeIsNotVisible" );
67
+ add ("waitUntilNodeIsVisible" );
68
+ add ("waitUntilProgressBarIsFinished" );
69
+ }};
70
+
71
+ static List <String > noWrappedAsyncFxKeywords = new ArrayList <String >() {{
72
+ add ("callObjectMethodInFxApplicationThread" );
73
+ add ("captureImage" );
74
+ add ("capturePrimaryScreen" );
75
+ add ("captureSceneContainingNode" );
76
+ add ("clearObjectMap" );
77
+ add ("closeJavafxApplication" );
78
+ add ("closeSwingApplication" );
79
+ add ("dragFrom" );
80
+ add ("dropTo" );
81
+ add ("dropToCoordinates" );
82
+ add ("getCurrentApplication" );
83
+ add ("getLibraryVersion" );
84
+ add ("getScreenshot Directory" );
85
+ add ("getScreenshotDirectory" );
86
+ add ("getSystemProperty" );
87
+ add ("isJavaAgent" );
88
+ add ("launchJavafxApplication" );
89
+ add ("launchSwingApplication" );
90
+ add ("launchSwingApplicationInSeparateThread" );
91
+ add ("logApplicationClasspath" );
92
+ add ("logSystemProperties" );
93
+ add ("moveTo" );
94
+ add ("nodeShouldBeHoverable" );
95
+ add ("nodeShouldNotBeHoverable" );
96
+ add ("pushManyTimes" );
97
+ add ("setImageLogging" );
98
+ add ("setSafeClicking" );
99
+ add ("setScreenshotDirectory" );
100
+ add ("setSystemProperty" );
101
+ add ("setTimeout" );
102
+ add ("setToClasspath" );
103
+ add ("setWriteSpeed" );
104
+ add ("waitForEventsInFxApplicationThread" );
105
+ add ("waitUntilElementDoesNotExists" );
106
+ add ("waitUntilElementExists" );
107
+ add ("waitUntilNodeIsEnabled" );
108
+ add ("waitUntilNodeIsNotEnabled" );
109
+ add ("waitUntilNodeIsNotVisible" );
110
+ add ("waitUntilNodeIsVisible" );
111
+ add ("waitUntilProgressBarIsFinished" );
112
+ add ("writeTo" );
113
+ }};
114
+
54
115
static List <String > includePatterns = new ArrayList <String >() {{
55
116
add ("javafxlibrary/keywords/AdditionalKeywords/*.class" );
56
117
add ("javafxlibrary/keywords/Keywords/*.class" );
@@ -91,11 +152,9 @@ public static String loadRobotLibraryVersion() {
91
152
92
153
@ Override
93
154
public Object runKeyword (String keywordName , List args , Map kwargs ) {
94
-
95
155
if (kwargs == null ) {
96
156
kwargs = new HashMap ();
97
157
}
98
-
99
158
List finalArgs ;
100
159
Map finalKwargs ;
101
160
@@ -108,110 +167,70 @@ public Object runKeyword(String keywordName, List args, Map kwargs) {
108
167
finalKwargs = kwargs ;
109
168
}
110
169
170
+ // Run keyword either in async or asyncFx thread with or without timeout
171
+ // Execution collects retval and retExcep from keyword
111
172
AtomicReference <Object > retval = new AtomicReference <>();
112
173
AtomicReference <RuntimeException > retExcep = new AtomicReference <>();
113
-
174
+ RobotLog . ignoreDuplicates ();
114
175
try {
115
- RobotLog .ignoreDuplicates ();
116
- // timeout + 500 ms so that underlying timeout has a chance to expire first
117
- waitFor (getWaitUntilTimeout (TimeUnit .MILLISECONDS ) + 500 , TimeUnit .MILLISECONDS , () -> {
118
-
119
- try {
176
+ if (noWrappedAsyncFxKeywords .contains (keywordName )) {
177
+ // no asyncFx thread
178
+ if (noLibraryKeywordTimeoutKeywords .contains (keywordName )) {
179
+ // without timeout
120
180
retval .set (super .runKeyword (keywordName , finalArgs , finalKwargs ));
121
- return true ;
122
-
123
- } catch (JavaFXLibraryTimeoutException jfxte ) {
124
- // timeout already expired, catch exception and jump out
125
- retExcep .set (jfxte );
126
- throw jfxte ;
127
-
128
- } catch (RuntimeException e ) {
129
- // catch exception and continue trying
130
- retExcep .set (e );
131
- return false ;
181
+ } else {
182
+ // in async thread
183
+ retval .set (waitForAsync (getLibraryKeywordTimeout (TimeUnit .MILLISECONDS ), () -> {
184
+ try {
185
+ return super .runKeyword (keywordName , finalArgs , finalKwargs );
186
+ } catch (RuntimeException rte ) {
187
+ retExcep .set (rte );
188
+ return null ;
189
+ }
190
+ }));
132
191
}
133
- });
134
- } catch (TimeoutException te ) {
135
- RobotLog .reset ();
136
- RuntimeException e = retExcep .get ();
137
- runOnFailure .runOnFailure ();
138
-
139
- if (e .getCause () instanceof JavaFXLibraryFatalException ) {
140
- RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary FATAL exception: \n " + Throwables .getStackTraceAsString (e ));
141
- throw e ;
142
- } else if (e .getCause () instanceof JavaFXLibraryNonFatalException ) {
143
- RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary NON-FATAL exception: \n " + Throwables .getStackTraceAsString (e ));
144
- throw e ;
145
192
} else {
146
- RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary RUNTIME exception: \n " + Throwables .getStackTraceAsString (e ));
147
- throw e ;
193
+ // in asyncFx thread
194
+ retval .set (waitForAsyncFx (getLibraryKeywordTimeout (TimeUnit .MILLISECONDS ), () -> {
195
+ try {
196
+ return super .runKeyword (keywordName , finalArgs , finalKwargs );
197
+ } catch (RuntimeException rte ) {
198
+ retExcep .set (rte );
199
+ return null ;
200
+ }
201
+ }));
202
+ waitForFxEvents ( 5 );
148
203
}
149
204
} catch (JavaFXLibraryTimeoutException jfxte ) {
150
- RobotLog .reset ();
151
- RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary TIMEOUT exception: \n " + Throwables .getStackTraceAsString (jfxte ));
152
- throw jfxte ;
205
+ // timeout already expired, catch exception and jump out
206
+ retExcep .set (jfxte );
207
+ } catch (RuntimeException rte ) {
208
+ // catch exception and continue trying
209
+ retExcep .set (rte );
153
210
}
154
- RobotLog .reset ();
155
- return retval .get ();
156
- }
157
-
158
- // overriding the run method to catch the control in case of failure, so that desired runOnFailureKeyword
159
- // can be executed in controlled manner.
160
- @ Override
161
- public Object runKeyword (String keywordName , List args ) {
162
- // TODO: Check if this is ever called anymore
163
- RobotLog .info ("runKeyword called with args ONLY" );
164
-
165
- List finalArgs ;
166
- // JavalibCore changes arguments of Call Method keywords to Strings after this check, so they need to handle their own objectMapping
167
- if (!(keywordName .equals ("callObjectMethod" ) || keywordName .equals ("callObjectMethodInFxApplicationThread" ))) {
168
- finalArgs = HelperFunctions .useMappedObjects (args );
169
- } else {
170
- finalArgs = args ;
171
- }
172
-
173
- AtomicReference <Object > retval = new AtomicReference <>();
174
- AtomicReference <RuntimeException > retExcep = new AtomicReference <>();
175
-
176
- try {
177
- RobotLog .ignoreDuplicates ();
178
- // timeout + 500 ms so that underlying timeout has a chance to expire first
179
- waitFor (getWaitUntilTimeout (TimeUnit .MILLISECONDS ) + 500 , TimeUnit .MILLISECONDS , () -> {
180
211
181
- try {
182
- retval .set (super .runKeyword (keywordName , finalArgs ));
183
- return true ;
184
-
185
- } catch (JavaFXLibraryTimeoutException jfxte ) {
186
- // timeout already expired, catch exception and jump out
187
- retExcep .set (jfxte );
188
- throw jfxte ;
189
-
190
- } catch (RuntimeException e ) {
191
- // catch exception and continue trying
192
- retExcep .set (e );
193
- return false ;
194
- }
195
- });
196
- } catch (TimeoutException te ) {
212
+ // in failure take screenshot and handle exception
213
+ if (retExcep .get ()!=null ) {
197
214
RobotLog .reset ();
198
215
RuntimeException e = retExcep .get ();
199
216
runOnFailure .runOnFailure ();
200
-
201
217
if (e .getCause () instanceof JavaFXLibraryFatalException ) {
202
218
RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary FATAL exception: \n " + Throwables .getStackTraceAsString (e ));
203
219
throw e ;
204
220
} else if (e .getCause () instanceof JavaFXLibraryNonFatalException ) {
205
221
RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary NON-FATAL exception: \n " + Throwables .getStackTraceAsString (e ));
206
222
throw e ;
223
+ } else if (e .getCause () instanceof TimeoutException ) {
224
+ throw new JavaFXLibraryNonFatalException ("Library keyword timeout (" + getLibraryKeywordTimeout () + "s) for keyword: " + keywordName );
225
+ } else if (e .getCause () instanceof IllegalArgumentException ) {
226
+ RobotLog .trace ("JavaFXLibrary: Caught IllegalArgumentException: \n " + Throwables .getStackTraceAsString (e ));
227
+ throw new JavaFXLibraryNonFatalException ("Illegal arguments for keyword '" + keywordName + "':\n " +
228
+ " ARGS: " + Arrays .toString (args .toArray ()) + "\n " +
229
+ " KWARGS: " + Arrays .toString (kwargs .entrySet ().toArray ()));
207
230
} else {
208
231
RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary RUNTIME exception: \n " + Throwables .getStackTraceAsString (e ));
209
232
throw e ;
210
233
}
211
- } catch (JavaFXLibraryTimeoutException jfxte ) {
212
- RobotLog .reset ();
213
- RobotLog .trace ("JavaFXLibrary: Caught JavaFXLibrary TIMEOUT exception: \n " + Throwables .getStackTraceAsString (jfxte ));
214
- throw jfxte ;
215
234
}
216
235
RobotLog .reset ();
217
236
return retval .get ();
0 commit comments