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