diff --git a/Unstable-Endpoint-SoapUI-project.xml b/Unstable-Endpoint-SoapUI-project.xml index 09c175a..30348c3 100644 --- a/Unstable-Endpoint-SoapUI-project.xml +++ b/Unstable-Endpoint-SoapUI-project.xml @@ -1,5 +1,5 @@ -http://05ten.setext/html; charset=UTF-8404htmlapplication/xml404application/xml200text/html404htmltext/html200htmltext/html; charset=UTF-8200htmltext/html; charset=iso-8859-1200htmlhttp://05ten.seNo AuthorizationSEQUENTIAL<xml-fragment/>UTF-8http://localhost:8080/everyTimehttp://05ten.se/404No Authorization<xml-fragment/>UTF-8http://localhost:8080/everyThirdTimehttp://05ten.se/bananananannananan404No AuthorizationtestCase.getProject().getRestMockServiceList().get(0).start()testCase.getProject().getRestMockServiceList().get(0).getMockRunner().stop()Response 1SEQUENCEFAILFAIL2SUCCESS!alwaysWorksSEQUENCE/* +http://localhost:8080text/html; charset=UTF-8404htmlapplication/xml404application/xml200text/html404htmltext/html200htmltext/html; charset=UTF-8200htmltext/html; charset=iso-8859-1200html0data0data<xml-fragment/>http://localhost:8080No AuthorizationSEQUENTIAL<xml-fragment/>UTF-8http://localhost:8080/everyTimehttp://05ten.se/404No Authorization<xml-fragment/>UTF-8http://localhost:8080/everyThirdTimehttp://05ten.se/bananananannananan404No Authorization2works_every_time_sometimes<xml-fragment/>UTF-8http://localhost:8080/everyThirdTimehttp://localhost/everyThirdTime/everyTime404No Authorization4works_every_third_time2<xml-fragment/>http://localhost:8080/everyTimehttp://localhost/everyTime/everyTime404No AuthorizationtestCase.getProject().getRestMockServiceList().get(0).start()testCase.getProject().getRestMockServiceList().get(0).getMockRunner().stop()Response 1SEQUENCEFAILFAIL2SUCCESS!alwaysWorksSEQUENCE/* // Script dispatcher is used to select a response based on the incoming request. // Here are few examples showing how to match based on path, query param, header and body diff --git a/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStep.java b/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStep.java index 55db2b4..ccecce0 100644 --- a/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStep.java +++ b/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStep.java @@ -5,18 +5,17 @@ import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase; import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepResult; import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepWithProperties; -import com.eviware.soapui.model.testsuite.TestCaseRunContext; -import com.eviware.soapui.model.testsuite.TestCaseRunner; -import com.eviware.soapui.model.testsuite.TestStep; -import com.eviware.soapui.model.testsuite.TestStepResult; +import com.eviware.soapui.model.testsuite.*; import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter; import com.eviware.soapui.plugins.auto.PluginTestStep; import com.eviware.soapui.support.UISupport; import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder; import com.eviware.soapui.support.xml.XmlObjectConfigurationReader; -import com.google.common.collect.Lists; import javax.swing.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.util.List; @PluginTestStep(typeName = "RepeatTestStep", name = "Repeat Test Step", @@ -28,6 +27,7 @@ public class RepeatTestStep extends WsdlTestStepWithProperties { private String targetTestStep; private static boolean actionGroupAdded = false; private int currentAttempts; + private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); public RepeatTestStep(WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest) { super(testCase, config, true, true); @@ -43,6 +43,13 @@ public void testCaseStarted(TestCaseRunner testCaseRunner) { } } }); + propertyChangeSupport.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if(evt.getPropertyName().equals(TestStep.NAME_PROPERTY) && evt.getOldValue().equals(RepeatTestStep.this.targetTestStep)){ + RepeatTestStep.this.targetTestStep = evt.getNewValue().toString(); + } + } + }); readConfig(config); } @@ -71,13 +78,13 @@ public ImageIcon getIcon() { } public TestStepResult run(TestCaseRunner testCaseRunner, TestCaseRunContext testCaseRunContext) { - WsdlTestStepResult result = new WsdlTestStepResult(this); + RepeatTestStepResult result = new RepeatTestStepResult(this); if(this.targetTestStep.equals("")){ result.setStatus(TestStepResult.TestStepStatus.FAILED); result.setError(new Exception("Unable to run repeat teststep without a target teststep")); return result; } - if (isPredecessorsSuccessful(testCaseRunner)) { + if (isIterationSuccessful(testCaseRunner)) { handleSuccessfulIteration(testCaseRunner, testCaseRunContext, result); } else if (currentAttempts < maxAttempts) { triggerNextIteration(testCaseRunner, result); @@ -94,50 +101,41 @@ private void triggerNextIteration(TestCaseRunner testCaseRunner, WsdlTestStepRes result.setStatus(TestStepResult.TestStepStatus.OK); } - private void handleSuccessfulIteration(TestCaseRunner testCaseRunner, TestCaseRunContext testCaseRunContext, WsdlTestStepResult result) { + private void handleSuccessfulIteration(TestCaseRunner runner, TestCaseRunContext testCaseRunContext, WsdlTestStepResult result) { result.setStatus(TestStepResult.TestStepStatus.OK); - boolean allTestsPassed = true; - for (TestStepResult testStepResult : testCaseRunner.getResults()) { - if (testStepResult.getStatus() != TestStepResult.TestStepStatus.OK) { - allTestsPassed = false; - break; - } - } - if (allTestsPassed) { + if (isIterationSuccessful(runner) && isPreviousRepeatStepsSuccessful(runner)) { testCaseRunContext.setProperty(TestCaseRunner.Status.class.getName(), TestCaseRunner.Status.RUNNING); + } else { + testCaseRunContext.setProperty(TestCaseRunner.Status.class.getName(), TestCaseRunner.Status.FAILED); } currentAttempts = 0; } - private boolean isPredecessorsSuccessful(TestCaseRunner runner) { - WsdlTestCase testCase = getTestCase(); - int targetIndex = testCase.getTestStepIndexByName(this.getTargetTestStep()); - int thisIndex = testCase.getTestStepIndexByName(this.getName()); - List includedTestSteps = Lists.newArrayList(); - int plusOneIfNotFirstIteration = currentAttempts == 0 ? 0 : 1; - - for (int i = targetIndex; i < thisIndex+plusOneIfNotFirstIteration; i++) { - TestStepResult testResult = runner.getResults().get(i); - includedTestSteps.add(testResult.getTestStep()); - boolean isFailedTestStep = testResult.getStatus() != WsdlTestStepResult.TestStepStatus.OK; - - if (isFailedTestStep) { - removeIterationResults(runner, includedTestSteps); + private boolean isPreviousRepeatStepsSuccessful(TestCaseRunner runner) { + List results = runner.getResults(); + for(TestStepResult result : results ){ + if(result instanceof RepeatTestStepResult && result.getStatus() == RepeatTestStepResult.TestStepStatus.FAILED){ return false; } } return true; } - private void removeIterationResults(TestCaseRunner runner, List includedTestSteps) { - for (TestStep includedTestStep : includedTestSteps) { - for (TestStepResult historicResult : runner.getResults()) { - if (historicResult.getTestStep().getName().equals(includedTestStep.getName())) { - runner.getResults().remove(historicResult); - break; - } + private boolean isIterationSuccessful(TestCaseRunner runner) { + List results = runner.getResults(); + WsdlTestCase testCase = getTestCase(); + int fromIndex = testCase.getTestStepIndexByName(this.getTargetTestStep()); + int toIndex = testCase.getTestStepIndexByName(this.getName()); + int distance = toIndex-fromIndex; + int topIndex = results.size()-1; + for (int i = topIndex; i > topIndex-distance; i--) { + TestStepResult testResult = results.get(i); + boolean isFailedTestStep = testResult.getStatus() != WsdlTestStepResult.TestStepStatus.OK; + if(isFailedTestStep){ + return false; } } + return true; } public int getMaxAttempts() { diff --git a/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStepDesktopPanel.java b/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStepDesktopPanel.java index 4c9b9fb..30aa722 100644 --- a/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStepDesktopPanel.java +++ b/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStepDesktopPanel.java @@ -1,6 +1,13 @@ package se.osten.flow.teststeps.repeat; +import com.eviware.soapui.SoapUI; import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase; +import com.eviware.soapui.impl.wsdl.teststeps.WsdlRunTestCaseTestStep; +import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep; +import com.eviware.soapui.model.ModelItem; +import com.eviware.soapui.model.support.TestSuiteListenerAdapter; +import com.eviware.soapui.model.testsuite.*; +import com.eviware.soapui.security.SecurityTest; import com.eviware.soapui.support.components.SimpleBindingForm; import com.eviware.soapui.ui.support.ModelItemDesktopPanel; import com.google.common.collect.Sets; @@ -10,8 +17,13 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.util.Set; +import static com.eviware.soapui.model.ModelItem.NAME_PROPERTY; + /** * Simple DesktopPanel that provides a basic UI for configuring the EMailTestStep. Should perhaps be improved with * a "Test" button and a log panel. @@ -19,13 +31,46 @@ public class RepeatTestStepDesktopPanel extends ModelItemDesktopPanel implements ActionListener { private PresentationModel pm; private SimpleBindingForm form; - private JComboBox maxAttempts; - private JComboBox targetTestStep; + private JComboBox maxAttemptsComboBox; + private JComboBox targetTestStepComboBox; + private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(getModelItem()); + private WsdlTestStep targetTestStep; public RepeatTestStepDesktopPanel(RepeatTestStep modelItem) { super(modelItem); this.pm = new PresentationModel(getModelItem()); this.form = new SimpleBindingForm(pm); + String testStepName = modelItem.getTargetTestStep(); + WsdlTestStep step = modelItem.getTestCase().getTestStepByName(testStepName); + if(step != null){ + this.targetTestStep = step; + this.targetTestStep.addPropertyChangeListener(testStepNameListener); + } + modelItem.getTestCase().getTestSuite().addTestSuiteListener(new TestSuiteListenerAdapter() { + private void resetIfTargetTestStep(TestStep activatedStep) { + if (targetTestStep.getName().equals(activatedStep.getName())){ + resetTargetTestStepComboBox(activatedStep.getName()); + } + if(activatedStep.getName().equals(getModelItem().getName())){ + resetTargetTestStepComboBox(targetTestStep.getName()); + } + } + + @Override + public void testStepAdded(TestStep testStep, int index) { + resetIfTargetTestStep(testStep); + } + + @Override + public void testStepRemoved(TestStep testStep, int index) { + resetIfTargetTestStep(testStep); + } + + @Override + public void testStepMoved(TestStep testStep, int fromIndex, int offset) { + resetIfTargetTestStep(testStep); + } + }); buildUI(); } @@ -40,10 +85,10 @@ private void buildUI() { private void addTargetTestStep() { Set testStepNamesWithinRange = getTestStepNamesWithinRange(); - this.targetTestStep = form.appendComboBox("Go to", testStepNamesWithinRange.toArray(), "TestStep to go to"); - this.targetTestStep.setEnabled(testStepNamesWithinRange.size() != 0); - this.targetTestStep.setSelectedItem(getModelItem().getTargetTestStep()); - this.targetTestStep.addActionListener(this); + this.targetTestStepComboBox = form.appendComboBox("Go to", testStepNamesWithinRange.toArray(), "TestStep to go to"); + this.targetTestStepComboBox.setEnabled(testStepNamesWithinRange.size() != 0); + this.targetTestStepComboBox.setSelectedItem(getModelItem().getTargetTestStep()); + this.targetTestStepComboBox.addActionListener(this); } private void addDescription() { @@ -56,9 +101,9 @@ private void addDescription() { } private void addMaxAttempts() { - this.maxAttempts = form.appendComboBox("Max attempts", new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, "Maximum number of attempts to run test-steps before giving up. 20-times is way beyond reasonable."); - this.maxAttempts.setSelectedItem(getModelItem().getMaxAttempts()); - this.maxAttempts.addActionListener(this); + this.maxAttemptsComboBox = form.appendComboBox("Max attempts", new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, "Maximum number of attempts to run test-steps before giving up. 20-times is way beyond reasonable."); + this.maxAttemptsComboBox.setSelectedItem(getModelItem().getMaxAttempts()); + this.maxAttemptsComboBox.addActionListener(this); } private Set getTestStepNamesWithinRange() { @@ -83,7 +128,45 @@ public boolean release() { } public void actionPerformed(ActionEvent e) { - getModelItem().setMaxAttempts(Integer.parseInt(maxAttempts.getSelectedItem().toString())); - getModelItem().setTargetTestStep(targetTestStep.getSelectedItem().toString()); + String targetTestStepName = targetTestStepComboBox.getSelectedItem().toString(); + getModelItem().setMaxAttempts(Integer.parseInt(maxAttemptsComboBox.getSelectedItem().toString())); + getModelItem().setTargetTestStep(targetTestStepName); + WsdlTestStep currentlySelectedTestStep = getModelItem().getTestCase().getTestStepByName(targetTestStepName); + if (!currentlySelectedTestStep.getName().equals(this.targetTestStep.getName())) { + this.targetTestStep.removePropertyChangeListener(testStepNameListener); + this.targetTestStep = currentlySelectedTestStep; + this.targetTestStep.addPropertyChangeListener(ModelItem.NAME_PROPERTY, testStepNameListener); + } + } + + private PropertyChangeListener testStepNameListener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(ModelItem.NAME_PROPERTY)) { + resetTargetTestStepComboBox(evt.getNewValue().toString()); + } + } + }; + + private void resetTargetTestStepComboBox(String targetTestStep) { + targetTestStepComboBox.removeActionListener(RepeatTestStepDesktopPanel.this); + targetTestStepComboBox.removeAllItems(); + for (String testStepName : getTestStepNamesWithinRange()) { + targetTestStepComboBox.addItem(testStepName); + } + if (targetTestStepComboBox.getItemCount() != 0) { + targetTestStepComboBox.setEnabled(targetTestStepComboBox.getItemCount() != 0); + } else { + targetTestStepComboBox.setEnabled(true); + if (getTestStepNamesWithinRange().contains(targetTestStep)) { + targetTestStepComboBox.setSelectedItem(targetTestStep); + } else { + int thisIndex = getModelItem().getTestCase().getTestStepIndexByName(getModelItem().getName()); + WsdlTestStep closestTestStep = getModelItem().getTestCase().getTestStepAt(thisIndex - 1); + this.targetTestStep = closestTestStep; + targetTestStepComboBox.setSelectedItem(closestTestStep.getName()); + } + } + getModelItem().setTargetTestStep(targetTestStep); + targetTestStepComboBox.addActionListener(RepeatTestStepDesktopPanel.this); } -} +} \ No newline at end of file diff --git a/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStepResult.java b/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStepResult.java new file mode 100644 index 0000000..d24fff0 --- /dev/null +++ b/src/main/java/se/osten/flow/teststeps/repeat/RepeatTestStepResult.java @@ -0,0 +1,13 @@ +package se.osten.flow.teststeps.repeat; + +import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep; +import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepResult; + +/** + * Created by mo916607 on 2017-08-02. + */ +public class RepeatTestStepResult extends WsdlTestStepResult { + public RepeatTestStepResult(WsdlTestStep testStep) { + super(testStep); + } +}