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