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.Dimension;
17 import java.awt.event.ActionEvent;
18 import java.awt.event.WindowAdapter;
19 import java.awt.event.WindowEvent;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import javax.swing.AbstractAction;
24 import javax.swing.Action;
25 import javax.swing.BorderFactory;
26 import javax.swing.JButton;
27 import javax.swing.JCheckBox;
28 import javax.swing.JDialog;
29 import javax.swing.JPanel;
30 import javax.swing.JScrollPane;
31 import javax.swing.JSplitPane;
32 import javax.swing.JTextArea;
33 import javax.swing.SwingUtilities;
34
35 import junit.framework.ComparisonFailure;
36
37 import org.apache.log4j.Logger;
38 import org.apache.xmlbeans.XmlAnySimpleType;
39 import org.apache.xmlbeans.XmlCursor;
40 import org.apache.xmlbeans.XmlObject;
41 import org.apache.xmlbeans.XmlOptions;
42 import org.apache.xmlbeans.XmlQName;
43 import org.custommonkey.xmlunit.Diff;
44 import org.custommonkey.xmlunit.Difference;
45 import org.custommonkey.xmlunit.DifferenceEngine;
46 import org.custommonkey.xmlunit.DifferenceListener;
47 import org.custommonkey.xmlunit.XMLAssert;
48 import org.w3c.dom.Attr;
49 import org.w3c.dom.Element;
50 import org.w3c.dom.Node;
51
52 import com.eviware.soapui.SoapUI;
53 import com.eviware.soapui.config.TestAssertionConfig;
54 import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
55 import com.eviware.soapui.impl.wsdl.WsdlInterface;
56 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
57 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathImpl;
58 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
59 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
60 import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
61 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
62 import com.eviware.soapui.impl.wsdl.teststeps.assertions.AbstractTestAssertionFactory;
63 import com.eviware.soapui.model.TestModelItem;
64 import com.eviware.soapui.model.iface.MessageExchange;
65 import com.eviware.soapui.model.iface.SubmitContext;
66 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
67 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
68 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
69 import com.eviware.soapui.model.support.XPathReference;
70 import com.eviware.soapui.model.support.XPathReferenceContainer;
71 import com.eviware.soapui.model.support.XPathReferenceImpl;
72 import com.eviware.soapui.model.testsuite.Assertable;
73 import com.eviware.soapui.model.testsuite.AssertionError;
74 import com.eviware.soapui.model.testsuite.AssertionException;
75 import com.eviware.soapui.model.testsuite.RequestAssertion;
76 import com.eviware.soapui.model.testsuite.ResponseAssertion;
77 import com.eviware.soapui.model.testsuite.TestProperty;
78 import com.eviware.soapui.model.testsuite.TestStep;
79 import com.eviware.soapui.support.StringUtils;
80 import com.eviware.soapui.support.UISupport;
81 import com.eviware.soapui.support.components.JUndoableTextArea;
82 import com.eviware.soapui.support.components.JXToolBar;
83 import com.eviware.soapui.support.types.StringList;
84 import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
85 import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
86 import com.eviware.soapui.support.xml.XmlUtils;
87 import com.jgoodies.forms.builder.ButtonBarBuilder;
88
89 /***
90 * Assertion that matches a specified XPath expression and its expected result
91 * against the associated WsdlTestRequests response message
92 *
93 * @author Ole.Matzura
94 */
95
96 public class XPathContainsAssertion extends WsdlMessageAssertion implements RequestAssertion, ResponseAssertion,
97 XPathReferenceContainer
98 {
99 private final static Logger log = Logger.getLogger( XPathContainsAssertion.class );
100 private String expectedContent;
101 private String path;
102 private JDialog configurationDialog;
103 private JTextArea pathArea;
104 private JTextArea contentArea;
105 private boolean configureResult;
106 private boolean allowWildcards;
107 private boolean ignoreNamspaceDifferences;
108
109 public static final String ID = "XPath Match";
110 public static final String LABEL = "XPath Match";
111 private JCheckBox allowWildcardsCheckBox;
112 private JCheckBox ignoreNamspaceDifferencesCheckBox;
113
114 public XPathContainsAssertion( TestAssertionConfig assertionConfig, Assertable assertable )
115 {
116 super( assertionConfig, assertable, true, true, true, true );
117
118 XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( getConfiguration() );
119 path = reader.readString( "path", null );
120 expectedContent = reader.readString( "content", null );
121 allowWildcards = reader.readBoolean( "allowWildcards", false );
122 ignoreNamspaceDifferences = reader.readBoolean( "ignoreNamspaceDifferences", false );
123 }
124
125 public String getExpectedContent()
126 {
127 return expectedContent;
128 }
129
130 public void setExpectedContent( String expectedContent )
131 {
132 this.expectedContent = expectedContent;
133 setConfiguration( createConfiguration() );
134 }
135
136 /***
137 * @deprecated
138 */
139
140 @Deprecated
141 public void setContent( String content )
142 {
143 setExpectedContent( content );
144 }
145
146 public String getPath()
147 {
148 return path;
149 }
150
151 public void setPath( String path )
152 {
153 this.path = path;
154 setConfiguration( createConfiguration() );
155 }
156
157 public boolean isAllowWildcards()
158 {
159 return allowWildcards;
160 }
161
162 public void setAllowWildcards( boolean allowWildcards )
163 {
164 this.allowWildcards = allowWildcards;
165 }
166
167 public boolean isIgnoreNamspaceDifferences()
168 {
169 return ignoreNamspaceDifferences;
170 }
171
172 public void setIgnoreNamspaceDifferences( boolean ignoreNamspaceDifferences )
173 {
174 this.ignoreNamspaceDifferences = ignoreNamspaceDifferences;
175 }
176
177 @Override
178 protected String internalAssertResponse( MessageExchange messageExchange, SubmitContext context )
179 throws AssertionException
180 {
181 if( !messageExchange.hasResponse() )
182 return "Missing Response";
183 else
184 return assertContent( messageExchange.getResponseContentAsXml(), context, "Response" );
185 }
186
187 public String assertContent( String response, SubmitContext context, String type ) throws AssertionException
188 {
189 try
190 {
191 if( path == null )
192 return "Missing path for XPath assertion";
193 if( expectedContent == null )
194 return "Missing content for XPath assertion";
195
196 XmlObject xml = XmlObject.Factory.parse( response );
197 String expandedPath = PropertyExpander.expandProperties( context, path );
198 XmlObject[] items = xml.selectPath( expandedPath );
199 AssertedXPathsContainer assertedXPathsContainer = ( AssertedXPathsContainer )context
200 .getProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY );
201
202 XmlObject contentObj = null;
203 String expandedContent = PropertyExpander.expandProperties( context, expectedContent );
204
205
206
207
208 if( !expandedPath.endsWith( "text()" ) )
209 {
210 try
211 {
212 contentObj = XmlObject.Factory.parse( expandedContent );
213 }
214 catch( Exception e )
215 {
216
217
218
219
220 }
221 }
222
223 if( items.length == 0 )
224 throw new Exception( "Missing content for xpath [" + path + "] in " + type );
225
226 XmlOptions options = new XmlOptions();
227 options.setSavePrettyPrint();
228 options.setSaveOuter();
229
230 for( int c = 0; c < items.length; c++ )
231 {
232 try
233 {
234 AssertedXPathImpl assertedXPathImpl = null;
235 if( assertedXPathsContainer != null )
236 {
237 String xpath = XmlUtils.createAbsoluteXPath( items[c].getDomNode() );
238 if( xpath != null )
239 {
240 XmlObject xmlObj = items[c];
241
242
243
244 assertedXPathImpl = new AssertedXPathImpl( this, xpath, xmlObj );
245 assertedXPathsContainer.addAssertedXPath( assertedXPathImpl );
246 }
247 }
248
249 if( contentObj == null )
250 {
251 if( items[c] instanceof XmlAnySimpleType && !( items[c] instanceof XmlQName ) )
252 {
253 String value = ( ( XmlAnySimpleType )items[c] ).getStringValue();
254 String expandedValue = PropertyExpander.expandProperties( context, value );
255 XMLAssert.assertEquals( expandedContent, expandedValue );
256 }
257 else
258 {
259 Node domNode = items[c].getDomNode();
260 if( domNode.getNodeType() == Node.ELEMENT_NODE )
261 {
262 String expandedValue = PropertyExpander.expandProperties( context, XmlUtils
263 .getElementText( ( Element )domNode ) );
264 XMLAssert.assertEquals( expandedContent, expandedValue );
265 }
266 else
267 {
268 String expandedValue = PropertyExpander.expandProperties( context, domNode.getNodeValue() );
269 XMLAssert.assertEquals( expandedContent, expandedValue );
270 }
271 }
272 }
273 else
274 {
275 compareValues( contentObj.xmlText( options ), items[c].xmlText( options ), items[c] );
276 }
277
278 break;
279 }
280 catch( Throwable e )
281 {
282 if( c == items.length - 1 )
283 throw e;
284 }
285 }
286 }
287 catch( Throwable e )
288 {
289 String msg = "";
290
291 if( e instanceof ComparisonFailure )
292 {
293 ComparisonFailure cf = ( ComparisonFailure )e;
294 String expected = cf.getExpected();
295 String actual = cf.getActual();
296
297
298
299
300
301
302
303 msg = "XPathContains comparison failed, expecting [" + expected + "], actual was [" + actual + "]";
304 }
305 else
306 {
307 msg = "XPathContains assertion failed for path [" + path + "] : " + e.getClass().getSimpleName() + ":"
308 + e.getMessage();
309 }
310
311 throw new AssertionException( new AssertionError( msg ) );
312 }
313
314 return type + " matches content for [" + path + "]";
315 }
316
317 private void compareValues( String expandedContent, String expandedValue, XmlObject object ) throws Exception
318 {
319 Diff diff = new Diff( expandedContent, expandedValue );
320 InternalDifferenceListener internalDifferenceListener = new InternalDifferenceListener();
321 diff.overrideDifferenceListener( internalDifferenceListener );
322
323 if( !diff.identical() )
324 throw new Exception( diff.toString() );
325
326 StringList nodesToRemove = internalDifferenceListener.getNodesToRemove();
327
328 if( !nodesToRemove.isEmpty() )
329 {
330 for( String node : nodesToRemove )
331 {
332 if( node == null )
333 continue;
334
335 int ix = node.indexOf( "\n/" );
336 if( ix != -1 )
337 node = node.substring( 0, ix + 1 ) + "/" + node.substring( ix + 1 );
338 else if( node.startsWith( "/" ) )
339 node = "/" + node;
340
341 XmlObject[] paths = object.selectPath( node );
342 if( paths.length > 0 )
343 {
344 Node domNode = paths[0].getDomNode();
345 if( domNode.getNodeType() == Node.ATTRIBUTE_NODE )
346 ( ( Attr )domNode ).getOwnerElement().removeAttributeNode( ( Attr )domNode );
347 else
348 domNode.getParentNode().removeChild( domNode );
349
350 object.set( object.copy() );
351 }
352 }
353 }
354 }
355
356 @Override
357 public boolean configure()
358 {
359 if( configurationDialog == null )
360 buildConfigurationDialog();
361
362 pathArea.setText( path );
363 contentArea.setText( expectedContent );
364 allowWildcardsCheckBox.setSelected( allowWildcards );
365
366 UISupport.showDialog( configurationDialog );
367 return configureResult;
368 }
369
370 protected void buildConfigurationDialog()
371 {
372 configurationDialog = new JDialog( UISupport.getMainFrame() );
373 configurationDialog.setTitle( "XPath Match configuration" );
374 configurationDialog.addWindowListener( new WindowAdapter()
375 {
376 @Override
377 public void windowOpened( WindowEvent event )
378 {
379 SwingUtilities.invokeLater( new Runnable()
380 {
381 public void run()
382 {
383 pathArea.requestFocusInWindow();
384 }
385 } );
386 }
387 } );
388
389 JPanel contentPanel = new JPanel( new BorderLayout() );
390 contentPanel.add( UISupport.buildDescription( "Specify xpath expression and expected result",
391 "declare namespaces with <code>declare namespace <prefix>='<namespace>';</code>", null ),
392 BorderLayout.NORTH );
393
394 JSplitPane splitPane = UISupport.createVerticalSplit();
395
396 pathArea = new JUndoableTextArea();
397 pathArea.setToolTipText( "Specifies the XPath expression to select from the message for validation" );
398
399 JPanel pathPanel = new JPanel( new BorderLayout() );
400 JXToolBar pathToolbar = UISupport.createToolbar();
401 addPathEditorActions( pathToolbar );
402
403 pathPanel.add( pathToolbar, BorderLayout.NORTH );
404 pathPanel.add( new JScrollPane( pathArea ), BorderLayout.CENTER );
405
406 splitPane.setTopComponent( UISupport.addTitledBorder( pathPanel, "XPath Expression" ) );
407
408 contentArea = new JUndoableTextArea();
409 contentArea.setToolTipText( "Specifies the expected result of the XPath expression" );
410
411 JPanel matchPanel = new JPanel( new BorderLayout() );
412 JXToolBar contentToolbar = UISupport.createToolbar();
413 addMatchEditorActions( contentToolbar );
414
415 matchPanel.add( contentToolbar, BorderLayout.NORTH );
416 matchPanel.add( new JScrollPane( contentArea ), BorderLayout.CENTER );
417
418 splitPane.setBottomComponent( UISupport.addTitledBorder( matchPanel, "Expected Result" ) );
419 splitPane.setDividerLocation( 150 );
420 splitPane.setBorder( BorderFactory.createEmptyBorder( 0, 1, 0, 1 ) );
421
422 contentPanel.add( splitPane, BorderLayout.CENTER );
423
424 ButtonBarBuilder builder = new ButtonBarBuilder();
425
426 ShowOnlineHelpAction showOnlineHelpAction = new ShowOnlineHelpAction( HelpUrls.XPATHASSERTIONEDITOR_HELP_URL );
427 builder.addFixed( UISupport.createToolbarButton( showOnlineHelpAction ) );
428 builder.addGlue();
429
430 JButton okButton = new JButton( new OkAction() );
431 builder.addFixed( okButton );
432 builder.addRelatedGap();
433 builder.addFixed( new JButton( new CancelAction() ) );
434
435 builder.setBorder( BorderFactory.createEmptyBorder( 1, 5, 5, 5 ) );
436
437 contentPanel.add( builder.getPanel(), BorderLayout.SOUTH );
438
439 configurationDialog.setContentPane( contentPanel );
440 configurationDialog.setSize( 600, 500 );
441 configurationDialog.setModal( true );
442 UISupport.initDialogActions( configurationDialog, showOnlineHelpAction, okButton );
443 }
444
445 protected void addPathEditorActions( JXToolBar toolbar )
446 {
447 toolbar.addFixed( new JButton( new DeclareNamespacesFromCurrentAction() ) );
448 }
449
450 protected void addMatchEditorActions( JXToolBar toolbar )
451 {
452 toolbar.addFixed( new JButton( new SelectFromCurrentAction() ) );
453 toolbar.addRelatedGap();
454 toolbar.addFixed( new JButton( new TestPathAction() ) );
455 allowWildcardsCheckBox = new JCheckBox( "Allow Wildcards" );
456
457 Dimension dim = new Dimension( 100, 20 );
458
459 allowWildcardsCheckBox.setSize( dim );
460 allowWildcardsCheckBox.setPreferredSize( dim );
461
462 allowWildcardsCheckBox.setOpaque( false );
463 toolbar.addRelatedGap();
464 toolbar.addFixed( allowWildcardsCheckBox );
465
466 Dimension largerDim = new Dimension( 200, 20 );
467 ignoreNamspaceDifferencesCheckBox = new JCheckBox( "Ignore namespace prefixes" );
468 ignoreNamspaceDifferencesCheckBox.setSize( largerDim );
469 ignoreNamspaceDifferencesCheckBox.setPreferredSize( largerDim );
470 ignoreNamspaceDifferencesCheckBox.setOpaque( false );
471 toolbar.addRelatedGap();
472 toolbar.addFixed( ignoreNamspaceDifferencesCheckBox );
473 }
474
475 public XmlObject createConfiguration()
476 {
477 XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
478 builder.add( "path", path );
479 builder.add( "content", expectedContent );
480 builder.add( "allowWildcards", allowWildcards );
481 builder.add( "ignoreNamspaceDifferences", ignoreNamspaceDifferences );
482 return builder.finish();
483 }
484
485 public void selectFromCurrent()
486 {
487 XmlCursor cursor = null;
488
489 try
490 {
491 String assertableContent = getAssertable().getAssertableContent();
492 if( assertableContent == null || assertableContent.trim().length() == 0 )
493 {
494 UISupport.showErrorMessage( "Missing content to select from" );
495 return;
496 }
497
498 XmlObject xml = XmlObject.Factory.parse( assertableContent );
499
500 String txt = pathArea == null || !pathArea.isVisible() ? getPath() : pathArea.getSelectedText();
501 if( txt == null )
502 txt = pathArea == null ? "" : pathArea.getText();
503
504 WsdlTestRunContext context = new WsdlTestRunContext( ( TestStep )getAssertable().getModelItem() );
505
506 String expandedPath = PropertyExpander.expandProperties( context, txt.trim() );
507
508 if( contentArea != null && contentArea.isVisible() )
509 contentArea.setText( "" );
510
511 cursor = xml.newCursor();
512 cursor.selectPath( expandedPath );
513 if( !cursor.toNextSelection() )
514 {
515 UISupport.showErrorMessage( "No match in current response" );
516 }
517 else if( cursor.hasNextSelection() )
518 {
519 UISupport.showErrorMessage( "More than one match in current response" );
520 }
521 else
522 {
523 String stringValue = XmlUtils.getValueForMatch( cursor );
524
525 if( contentArea != null && contentArea.isVisible() )
526 contentArea.setText( stringValue );
527 else
528 setExpectedContent( stringValue );
529 }
530 }
531 catch( Throwable e )
532 {
533 UISupport.showErrorMessage( e.toString() );
534 SoapUI.logError( e );
535 }
536 finally
537 {
538 if( cursor != null )
539 cursor.dispose();
540 }
541 }
542
543 private final class InternalDifferenceListener implements DifferenceListener
544 {
545 private StringList nodesToRemove = new StringList();
546
547 public int differenceFound( Difference diff )
548 {
549 if( allowWildcards
550 && ( diff.getId() == DifferenceEngine.TEXT_VALUE.getId() || diff.getId() == DifferenceEngine.ATTR_VALUE
551 .getId() ) )
552 {
553 if( diff.getControlNodeDetail().getValue().equals( "*" ) )
554 {
555 Node node = diff.getTestNodeDetail().getNode();
556 String xp = XmlUtils.createAbsoluteXPath( node.getNodeType() == Node.ATTRIBUTE_NODE ? node : node
557 .getParentNode() );
558 nodesToRemove.add( xp );
559 return Diff.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
560 }
561 }
562 else if( ignoreNamspaceDifferences && diff.getId() == DifferenceEngine.NAMESPACE_PREFIX_ID )
563 {
564 return Diff.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
565 }
566
567 return Diff.RETURN_ACCEPT_DIFFERENCE;
568 }
569
570 public void skippedComparison( Node arg0, Node arg1 )
571 {
572
573 }
574
575 public StringList getNodesToRemove()
576 {
577 return nodesToRemove;
578 }
579 }
580
581 public class OkAction extends AbstractAction
582 {
583 public OkAction()
584 {
585 super( "Save" );
586 }
587
588 public void actionPerformed( ActionEvent arg0 )
589 {
590 setPath( pathArea.getText().trim() );
591 setExpectedContent( contentArea.getText() );
592 setAllowWildcards( allowWildcardsCheckBox.isSelected() );
593 setIgnoreNamspaceDifferences( ignoreNamspaceDifferencesCheckBox.isSelected() );
594 setConfiguration( createConfiguration() );
595 configureResult = true;
596 configurationDialog.setVisible( false );
597 }
598 }
599
600 public class CancelAction extends AbstractAction
601 {
602 public CancelAction()
603 {
604 super( "Cancel" );
605 }
606
607 public void actionPerformed( ActionEvent arg0 )
608 {
609 configureResult = false;
610 configurationDialog.setVisible( false );
611 }
612 }
613
614 public class DeclareNamespacesFromCurrentAction extends AbstractAction
615 {
616 public DeclareNamespacesFromCurrentAction()
617 {
618 super( "Declare" );
619 putValue( Action.SHORT_DESCRIPTION, "Add namespace declaration from current message to XPath expression" );
620 }
621
622 public void actionPerformed( ActionEvent arg0 )
623 {
624 try
625 {
626 String content = getAssertable().getAssertableContent();
627 if( content != null && content.trim().length() > 0 )
628 {
629 pathArea.setText( XmlUtils.declareXPathNamespaces( content ) + pathArea.getText() );
630 }
631 else if( UISupport.confirm( "Declare namespaces from schema instead?", "Missing Response" ) )
632 {
633 pathArea.setText( XmlUtils.declareXPathNamespaces( ( WsdlInterface )getAssertable().getInterface() )
634 + pathArea.getText() );
635 }
636 }
637 catch( Exception e )
638 {
639 log.error( e.getMessage() );
640 }
641 }
642 }
643
644 public class TestPathAction extends AbstractAction
645 {
646 public TestPathAction()
647 {
648 super( "Test" );
649 putValue( Action.SHORT_DESCRIPTION,
650 "Tests the XPath expression for the current message against the Expected Content field" );
651 }
652
653 public void actionPerformed( ActionEvent arg0 )
654 {
655 String oldPath = getPath();
656 String oldContent = getExpectedContent();
657 boolean oldAllowWildcards = isAllowWildcards();
658
659 setPath( pathArea.getText().trim() );
660 setExpectedContent( contentArea.getText() );
661 setAllowWildcards( allowWildcardsCheckBox.isSelected() );
662 setIgnoreNamspaceDifferences( ignoreNamspaceDifferencesCheckBox.isSelected() );
663
664 try
665 {
666 String msg = assertContent( getAssertable().getAssertableContent(), new WsdlTestRunContext(
667 ( TestStep )getAssertable().getModelItem() ), "Response" );
668 UISupport.showInfoMessage( msg, "Success" );
669 }
670 catch( AssertionException e )
671 {
672 UISupport.showErrorMessage( e.getMessage() );
673 }
674
675 setPath( oldPath );
676 setExpectedContent( oldContent );
677 setAllowWildcards( oldAllowWildcards );
678 }
679 }
680
681 public class SelectFromCurrentAction extends AbstractAction
682 {
683 public SelectFromCurrentAction()
684 {
685 super( "Select from current" );
686 putValue( Action.SHORT_DESCRIPTION,
687 "Selects the XPath expression from the current message into the Expected Content field" );
688 }
689
690 public void actionPerformed( ActionEvent arg0 )
691 {
692 selectFromCurrent();
693 }
694 }
695
696 @Override
697 protected String internalAssertRequest( MessageExchange messageExchange, SubmitContext context )
698 throws AssertionException
699 {
700 if( !messageExchange.hasRequest( true ) )
701 return "Missing Request";
702 else
703 return assertContent( messageExchange.getRequestContent(), context, "Request" );
704 }
705
706 public JTextArea getContentArea()
707 {
708 return contentArea;
709 }
710
711 public JTextArea getPathArea()
712 {
713 return pathArea;
714 }
715
716 @Override
717 public PropertyExpansion[] getPropertyExpansions()
718 {
719 List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
720
721 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( getAssertable().getModelItem(), this,
722 "expectedContent" ) );
723 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( getAssertable().getModelItem(), this, "path" ) );
724
725 return result.toArray( new PropertyExpansion[result.size()] );
726 }
727
728 public XPathReference[] getXPathReferences()
729 {
730 List<XPathReference> result = new ArrayList<XPathReference>();
731
732 if( StringUtils.hasContent( getPath() ) )
733 {
734 TestModelItem testStep = ( TestModelItem )getAssertable().getModelItem();
735 TestProperty property = testStep instanceof WsdlTestRequestStep ? testStep.getProperty( "Response" )
736 : testStep.getProperty( "Request" );
737 result.add( new XPathReferenceImpl( "XPath for " + getName() + " XPathContainsAssertion in "
738 + testStep.getName(), property, this, "path" ) );
739 }
740
741 return result.toArray( new XPathReference[result.size()] );
742 }
743
744 public static class Factory extends AbstractTestAssertionFactory
745 {
746 public Factory()
747 {
748 super( XPathContainsAssertion.ID, XPathContainsAssertion.LABEL, XPathContainsAssertion.class );
749 }
750 }
751 }