1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps.assertions.basic;
14
15 import java.awt.BorderLayout;
16 import java.awt.Component;
17 import java.awt.Dimension;
18 import java.awt.event.ActionEvent;
19 import java.awt.event.MouseAdapter;
20 import java.awt.event.MouseEvent;
21
22 import javax.swing.AbstractAction;
23 import javax.swing.Action;
24 import javax.swing.BorderFactory;
25 import javax.swing.Box;
26 import javax.swing.JButton;
27 import javax.swing.JComponent;
28 import javax.swing.JDialog;
29 import javax.swing.JLabel;
30 import javax.swing.JPanel;
31 import javax.swing.JSplitPane;
32
33 import org.apache.log4j.Logger;
34 import org.apache.xmlbeans.XmlObject;
35
36 import com.eviware.soapui.SoapUI;
37 import com.eviware.soapui.config.TestAssertionConfig;
38 import com.eviware.soapui.impl.rest.RestRequestInterface;
39 import com.eviware.soapui.impl.support.AbstractHttpRequestInterface;
40 import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
41 import com.eviware.soapui.impl.wsdl.panels.mockoperation.WsdlMockResponseMessageExchange;
42 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
43 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
44 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
45 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
46 import com.eviware.soapui.impl.wsdl.teststeps.HttpResponseMessageExchange;
47 import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStepInterface;
48 import com.eviware.soapui.impl.wsdl.teststeps.RestResponseMessageExchange;
49 import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStepInterface;
50 import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
51 import com.eviware.soapui.impl.wsdl.teststeps.WsdlMockResponseTestStep;
52 import com.eviware.soapui.impl.wsdl.teststeps.WsdlResponseMessageExchange;
53 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
54 import com.eviware.soapui.impl.wsdl.teststeps.assertions.AbstractTestAssertionFactory;
55 import com.eviware.soapui.model.iface.MessageExchange;
56 import com.eviware.soapui.model.iface.SubmitContext;
57 import com.eviware.soapui.model.testsuite.Assertable;
58 import com.eviware.soapui.model.testsuite.AssertionError;
59 import com.eviware.soapui.model.testsuite.AssertionException;
60 import com.eviware.soapui.model.testsuite.RequestAssertion;
61 import com.eviware.soapui.model.testsuite.ResponseAssertion;
62 import com.eviware.soapui.model.testsuite.TestStep;
63 import com.eviware.soapui.support.UISupport;
64 import com.eviware.soapui.support.components.JXToolBar;
65 import com.eviware.soapui.support.log.JLogList;
66 import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
67 import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
68 import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
69 import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
70 import com.jgoodies.forms.builder.ButtonBarBuilder;
71
72 /***
73 * Assertion performed by a custom Grooy Script
74 *
75 * @author ole.matzura
76 */
77
78 public class GroovyScriptAssertion extends WsdlMessageAssertion implements RequestAssertion, ResponseAssertion
79 {
80 public static final String ID = "GroovyScriptAssertion";
81 public static final String LABEL = "Script Assertion";
82 private String scriptText;
83 private SoapUIScriptEngine scriptEngine;
84 private JDialog dialog;
85 private GroovyScriptAssertionPanel groovyScriptAssertionPanel;
86 private String oldScriptText;
87
88 public GroovyScriptAssertion( TestAssertionConfig assertionConfig, Assertable modelItem )
89 {
90 super( assertionConfig, modelItem, true, true, true, false );
91
92 XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( getConfiguration() );
93 scriptText = reader.readString( "scriptText", "" );
94
95 scriptEngine = SoapUIScriptEngineRegistry.create( this );
96 scriptEngine.setScript( scriptText );
97 }
98
99 @Override
100 protected String internalAssertRequest( MessageExchange messageExchange, SubmitContext context )
101 throws AssertionException
102 {
103 return assertScript( messageExchange, context, SoapUI.ensureGroovyLog() );
104 }
105
106 private String assertScript( MessageExchange messageExchange, SubmitContext context, Logger log )
107 throws AssertionException
108 {
109 try
110 {
111 scriptEngine.setVariable( "context", context );
112 scriptEngine.setVariable( "messageExchange", messageExchange );
113 scriptEngine.setVariable( "log", log );
114 scriptEngine.setVariable( "assertion", this );
115
116 Object result = scriptEngine.run();
117 return result == null ? null : result.toString();
118 }
119 catch( Throwable e )
120 {
121 throw new AssertionException( new AssertionError( e.getMessage() ) );
122 }
123 finally
124 {
125 scriptEngine.clearVariables();
126 }
127 }
128
129 @Override
130 protected String internalAssertResponse( MessageExchange messageExchange, SubmitContext context )
131 throws AssertionException
132 {
133 return assertScript( messageExchange, context, SoapUI.ensureGroovyLog() );
134 }
135
136 @Override
137 public boolean configure()
138 {
139 if( dialog == null )
140 {
141 buildDialog();
142 }
143
144 oldScriptText = scriptText;
145 UISupport.showDialog( dialog );
146 return true;
147 }
148
149 protected void buildDialog()
150 {
151 dialog = new JDialog( UISupport.getMainFrame(), "Script Assertion", true );
152 groovyScriptAssertionPanel = new GroovyScriptAssertionPanel();
153 dialog.setContentPane( groovyScriptAssertionPanel );
154 UISupport.initDialogActions( dialog, groovyScriptAssertionPanel.getShowOnlineHelpAction(),
155 groovyScriptAssertionPanel.getDefaultButton() );
156 dialog.setSize( 600, 500 );
157 dialog.setModal( true );
158 dialog.pack();
159 }
160
161 protected GroovyScriptAssertionPanel getScriptAssertionPanel()
162 {
163 return groovyScriptAssertionPanel;
164 }
165
166 protected XmlObject createConfiguration()
167 {
168 XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
169 builder.add( "scriptText", scriptText );
170 return builder.finish();
171 }
172
173 public String getScriptText()
174 {
175 return scriptText;
176 }
177
178 public void setScriptText( String scriptText )
179 {
180 this.scriptText = scriptText;
181 scriptEngine.setScript( scriptText );
182 setConfiguration( createConfiguration() );
183 }
184
185 protected class GroovyScriptAssertionPanel extends JPanel
186 {
187 private GroovyEditor editor;
188 private JSplitPane mainSplit;
189 private JLogList logArea;
190 private RunAction runAction = new RunAction();
191 private Logger logger;
192 private JButton okButton;
193 private ShowOnlineHelpAction showOnlineHelpAction;
194 public String oldscriptText;
195
196 public GroovyScriptAssertionPanel()
197 {
198 super( new BorderLayout() );
199
200 buildUI();
201 setPreferredSize( new Dimension( 600, 440 ) );
202
203 logger = Logger.getLogger( "ScriptAssertion." + getName() );
204 editor.requestFocusInWindow();
205 }
206
207 public GroovyEditor getGroovyEditor()
208 {
209 return editor;
210 }
211
212 public void release()
213 {
214 logArea.release();
215 editor.release();
216 logger = null;
217 }
218
219 private void buildUI()
220 {
221 editor = new GroovyEditor( new ScriptStepGroovyEditorModel() );
222
223 logArea = new JLogList( "Groovy Test Log" );
224 logArea.addLogger( "ScriptAssertion." + getName(), true );
225 logArea.getLogList().addMouseListener( new MouseAdapter()
226 {
227
228 public void mouseClicked( MouseEvent e )
229 {
230 if( e.getClickCount() < 2 )
231 return;
232
233 String value = logArea.getLogList().getSelectedValue().toString();
234 if( value == null )
235 return;
236
237 editor.selectError( value );
238 }
239 } );
240
241 editor.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder( 0, 3, 0, 3 ), editor
242 .getBorder() ) );
243
244 mainSplit = UISupport.createVerticalSplit( editor, logArea );
245 mainSplit.setDividerLocation( 280 );
246 mainSplit.setResizeWeight( 0.8 );
247 add( mainSplit, BorderLayout.CENTER );
248 add( buildToolbar(), BorderLayout.NORTH );
249 add( buildStatusBar(), BorderLayout.SOUTH );
250 }
251
252 public JButton getDefaultButton()
253 {
254 return okButton;
255 }
256
257 public ShowOnlineHelpAction getShowOnlineHelpAction()
258 {
259 return showOnlineHelpAction;
260 }
261
262 private Component buildStatusBar()
263 {
264 ButtonBarBuilder builder = new ButtonBarBuilder();
265
266 showOnlineHelpAction = new ShowOnlineHelpAction( HelpUrls.GROOVYASSERTION_HELP_URL );
267 builder.addFixed( UISupport.createToolbarButton( showOnlineHelpAction ) );
268 builder.addGlue();
269 okButton = new JButton( new OkAction() );
270 builder.addFixed( okButton );
271 builder.addRelatedGap();
272 builder.addFixed( new JButton( new CancelAction() ) );
273 builder.setBorder( BorderFactory.createEmptyBorder( 0, 3, 3, 3 ) );
274 return builder.getPanel();
275 }
276
277 private JComponent buildToolbar()
278 {
279 JXToolBar toolBar = UISupport.createToolbar();
280 JButton runButton = UISupport.createToolbarButton( runAction );
281 toolBar.add( runButton );
282 toolBar.add( Box.createHorizontalGlue() );
283 JLabel label = new JLabel( "<html>Script is invoked with <code>log</code>, <code>context</code> "
284 + "and <code>messageExchange</code> variables</html>" );
285 label.setToolTipText( label.getText() );
286 label.setMaximumSize( label.getPreferredSize() );
287
288 toolBar.addFixed( label );
289 toolBar.addSpace( 3 );
290
291 return toolBar;
292 }
293
294 private final class OkAction extends AbstractAction
295 {
296 public OkAction()
297 {
298 super( "OK" );
299 }
300
301 public void actionPerformed( ActionEvent e )
302 {
303 dialog.setVisible( false );
304 setScriptText( editor.getEditArea().getText() );
305 }
306 }
307
308 private final class CancelAction extends AbstractAction
309 {
310 public CancelAction()
311 {
312 super( "Cancel" );
313 }
314
315 public void actionPerformed( ActionEvent e )
316 {
317 dialog.setVisible( false );
318 editor.getEditArea().setText( oldScriptText );
319 }
320 }
321
322 private class ScriptStepGroovyEditorModel extends AbstractGroovyEditorModel
323 {
324 public ScriptStepGroovyEditorModel()
325 {
326 super( new String[] { "log", "context", "messageExchange" }, getAssertable().getModelItem(), "Assertion" );
327 }
328
329 public Action getRunAction()
330 {
331 return runAction;
332 }
333
334 public String getScript()
335 {
336 return getScriptText();
337 }
338
339 public void setScript( String text )
340 {
341
342 }
343 }
344
345 private class RunAction extends AbstractAction
346 {
347 public RunAction()
348 {
349 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ) );
350 putValue( Action.SHORT_DESCRIPTION,
351 "Runs this assertion script against the last messageExchange with a mock testContext" );
352 }
353
354 public void actionPerformed( ActionEvent e )
355 {
356 TestStep testStep = ( TestStep )getAssertable().getModelItem();
357 MessageExchange exchange = null;
358
359 if( testStep instanceof WsdlTestRequestStep )
360 {
361 WsdlTestRequestStep testRequestStep = ( WsdlTestRequestStep )testStep;
362 exchange = new WsdlResponseMessageExchange( testRequestStep.getTestRequest() );
363 ( ( WsdlResponseMessageExchange )exchange ).setResponse( testRequestStep.getTestRequest().getResponse() );
364 }
365 else if( testStep instanceof RestTestRequestStepInterface )
366 {
367 RestTestRequestStepInterface testRequestStep = ( RestTestRequestStepInterface )testStep;
368 exchange = new RestResponseMessageExchange( ( RestRequestInterface )testRequestStep.getTestRequest() );
369 ( ( RestResponseMessageExchange )exchange )
370 .setResponse( ( ( AbstractHttpRequestInterface<?> )testRequestStep.getTestRequest() )
371 .getResponse() );
372 }
373 else if( testStep instanceof HttpTestRequestStepInterface )
374 {
375 HttpTestRequestStepInterface testRequestStep = ( HttpTestRequestStepInterface )testStep;
376 exchange = new HttpResponseMessageExchange( testRequestStep.getTestRequest() );
377 ( ( HttpResponseMessageExchange )exchange )
378 .setResponse( ( ( AbstractHttpRequestInterface<?> )testRequestStep.getTestRequest() )
379 .getResponse() );
380 }
381 else if( testStep instanceof WsdlMockResponseTestStep )
382 {
383 WsdlMockResponseTestStep mockResponseStep = ( WsdlMockResponseTestStep )testStep;
384 exchange = new WsdlMockResponseMessageExchange( mockResponseStep.getMockResponse() );
385 }
386
387 try
388 {
389 setScriptText( editor.getEditArea().getText() );
390 String result = assertScript( exchange, new WsdlTestRunContext( testStep ), logger );
391 UISupport
392 .showInfoMessage( "Script Assertion Passed" + ( ( result == null ) ? "" : ": [" + result + "]" ) );
393 }
394 catch( AssertionException e1 )
395 {
396 UISupport.showErrorMessage( e1.getMessage() );
397 }
398 catch( Throwable t )
399 {
400 SoapUI.logError( t );
401 UISupport.showErrorMessage( t.getMessage() );
402 }
403
404 editor.requestFocusInWindow();
405 }
406 }
407 }
408
409 @Override
410 public void release()
411 {
412 super.release();
413 scriptEngine.release();
414
415 if( groovyScriptAssertionPanel != null )
416 groovyScriptAssertionPanel.release();
417 }
418
419 public static class Factory extends AbstractTestAssertionFactory
420 {
421 public Factory()
422 {
423 super( GroovyScriptAssertion.ID, GroovyScriptAssertion.LABEL, GroovyScriptAssertion.class );
424 }
425
426 @Override
427 public Class<? extends WsdlMessageAssertion> getAssertionClassType()
428 {
429 return GroovyScriptAssertion.class;
430 }
431
432 }
433 }