Contributions
- 12 years agoPlace ReadyAPI QuestionsReadyAPI Questions1.7KViews0likes0Comments
Re: Share your components here
njcoutinho wrote: SmartBear Support wrote: thzinc wrote: Component Name Custom HTTP Runner Developer Daniel James, Casting Networks, Inc. [...] Looking really good Daniel! In case you haven't already noticed, your component have been published in the custom components gallery. Henrik loadUI developer Hi Daniel , Where can i find the documentation of your product I just replied to your post at viewtopic.php?f=10&t=13056&p=42078&sid=b0c689d8b822911fd4da3a8862037e81#p4207812 years agoPlace ReadyAPI QuestionsReadyAPI Questions1.5KViews0likes0CommentsRe: Custom HTTP runner
I realize you has asked this question just over a year ago, but I just saw the question now. The Custom HTTP Runner works just like the standard Web Page Runner, except that you can specify an HTTP method (verb) and the HTTP entity body. (i.e., the body of the request) The HTTP entity body for a POST request will be the application/x-www-form-urlencoded data. For example, if you are going to POST to the URL with some form data: URL: http://www.example.com/controller/HandleAction.do Form data: name=Daniel date=2013-03-30 note=Lorem ipsum dolor sit amet Then the relevant info you'd put in the Custom HTTP Runner would be: HTTP Method: POST URL: http://www.example.com/controller/HandleAction.do HTTP Entity Body: name=Daniel&date=2013-03-30¬e=Lorem%20ipsum%20dolor%20sit%20amet Basically, the HTTP Entity Body looks very similar to a GET request's querystring. Hopefully this is helpful, if not to you, to anyone else who might be searching the forums. Daniel James12 years agoPlace ReadyAPI QuestionsReadyAPI Questions836Views0likes0CommentsRe: How to pass the postdata in Load UI
Sara, I recently posted a custom component that allows you to execute POST requests and send post data (HTTP request entity body). Please see my post at viewtopic.php?f=10&t=7457&p=24052#p24052. I'd love to know if this helps. Daniel James Casting Networks, Inc.13 years agoPlace ReadyAPI QuestionsReadyAPI Questions1.2KViews0likes0CommentsRe: Share your components here
Component Name Custom HTTP Runner Developer Daniel James, Casting Networks, Inc. Description Derivative of Web Runner, Custom HTTP Runner allows you to execute an HTTP request using any method desired. (e.g., GET, HEAD, POST, PUT, any other arbitrary verb) The Custom HTTP Runner also allows you to specify a pre-encoded HTTP entity body, which is especially useful for POST or PUT requests. Source Code // Custom HTTP Runner, Copyright 2011 Casting Networks, Inc. // // Derivative work of Web Runner, Copyright 2011 eviware software ab // // Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European Commission - subsequent // versions of the EUPL (the "Licence"); // You may not use this work except in compliance with the Licence. // You may obtain a copy of the Licence at: // // http://ec.europa.eu/idabc/eupl5 // // Unless required by applicable law or agreed to in writing, software distributed under the Licence is // distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either // express or implied. See the Licence for the specific language governing permissions and limitations // under the Licence. // /** * Sends an HTTP request * * @id com.castingnetworksinc.CustomHTTPRunner * @help http://www.loadui.org/Runners/web-page-runner-component.html * @name Custom HTTP Runner * @category runners * @dependency org.apache.httpcomponents:httpcore:4.1 * @dependency org.apache.httpcomponents:httpclient:4.1.1 */ import org.apache.http.* import org.apache.http.client.* import org.apache.http.auth.* import org.apache.http.conn.params.* import org.apache.http.conn.scheme.* import org.apache.http.client.methods.* import org.apache.http.conn.ClientConnectionManager import org.apache.http.entity.StringEntity import org.apache.http.util.EntityUtils import org.apache.http.impl.client.DefaultHttpClient import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager import com.eviware.loadui.api.events.ActionEvent import com.eviware.loadui.api.events.PropertyEvent import com.eviware.loadui.api.model.CanvasItem import com.eviware.loadui.impl.component.categories.RunnerBase.SampleCancelledException import com.eviware.loadui.impl.component.ActivityStrategies import com.eviware.loadui.util.layout.DelayedFormattedString import com.eviware.loadui.util.ReleasableUtils import java.util.concurrent.TimeUnit import org.apache.http.conn.scheme.Scheme import org.apache.http.conn.ssl.SSLSocketFactory import java.net.URI import javax.net.ssl.SSLContext import javax.net.ssl.KeyManager import javax.net.ssl.TrustManager import javax.net.ssl.X509TrustManager import java.security.cert.X509Certificate import java.security.cert.CertificateException import java.security.SecureRandom import java.util.HashMap import java.util.Map import java.util.concurrent.TimeUnit // Create a custom HTTP request based off of the Apache HTTP Client base class class HttpCustom extends HttpEntityEnclosingRequestBase { def _method HttpCustom(method, uri) { super.setURI(URI.create(uri)) _method = method } String getMethod() { _method } } scheduleAtFixedRate( { updateLed() }, 500, 500, TimeUnit.MILLISECONDS ) createOutput( 'statisticsOutput', 'Statistics', 'Connect to a Statistics component to feed it with the displayed values.' ) //SSL support, trust all certificates and hostnames. class NaiveTrustManager implements X509TrustManager { void checkClientTrusted ( X509Certificate[] cert, String authType ) throws CertificateException {} void checkServerTrusted ( X509Certificate[] cert, String authType ) throws CertificateException {} X509Certificate[] getAcceptedIssuers () { null } } def sslContext = SSLContext.getInstance("SSL") TrustManager[] tms = [ new NaiveTrustManager() ] sslContext.init( new KeyManager[0], tms, new SecureRandom() ) def sslSocketFactory = new SSLSocketFactory( sslContext ) sslSocketFactory.setHostnameVerifier( SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER ) def sr = new SchemeRegistry() sr.register( new Scheme( "http", 80, PlainSocketFactory.socketFactory ) ) sr.register( new Scheme( "https", 443, sslSocketFactory ) ) def cm = new ThreadSafeClientConnManager( sr ) cm.maxTotal = 50000 cm.defaultMaxPerRoute = 50000 //Properties createProperty( 'url', String ) { -> validateUrl() } // Default method to GET createProperty( 'method', String, 'GET' ) createProperty( 'entityBody', String ) createProperty( 'outputBody', Boolean, false ) createProperty( 'readResponse', Boolean, false ) createProperty( 'errorCodeList', String ) createProperty( 'proxyHost', String ) createProperty( 'proxyPort', Long ) createProperty( 'proxyUsername', String ) proxyPassword = createProperty( '_proxyPassword', String ) authUsername = createProperty( '_authUsername', String ) authPassword = createProperty( '_authPassword', String ) http = new DefaultHttpClient( cm ) inlineUrlAuthUsername = null inlineUrlAuthPassword = null def runningSamples = ([] as Set).asSynchronized() runAction = null def dummyUrl = "http://GoSpamYourself.com" validateUrl = { if( url.value && !( url.value.toLowerCase().startsWith( "http://" ) || url.value.toLowerCase().startsWith( "https://" ) ) ) { url.value = "http://" + url.value } if( url.value =~ /https?:\/\/(www\.)?(eviware\.com|(soapui|loadui)\.org)(\/.*)?/ ) url.value = dummyUrl // extract possible username and password from username:password@domain syntax matcher = url.value?.replace( "http://", "" ) =~ /([^:]+):([^@]+)@(.+)/ if ( matcher ) { inlineUrlAuthUsername = matcher[0][1] inlineUrlAuthPassword = matcher[0][2] } else { inlineUrlAuthUsername = inlineUrlAuthPassword = null } updateAuth() setInvalid( !url.value || url.value == dummyUrl ) runAction?.enabled = !isInvalid() } updateLed = { setActivityStrategy( runAction?.enabled ? ( currentlyRunning > 0 ? ActivityStrategies.BLINKING : ActivityStrategies.ON ) : ActivityStrategies.OFF ) } updateProxy = { if( proxyHost.value?.trim() && proxyPort.value ) { HttpHost hcProxyHost = new HttpHost( proxyHost.value, (int)proxyPort.value, "http" ) http.params.setParameter( ConnRoutePNames.DEFAULT_PROXY, hcProxyHost ) if( proxyUsername.value?.trim() && proxyPassword.value ) { http.credentialsProvider.setCredentials( new AuthScope( proxyHost.value, (int)proxyPort.value ), new UsernamePasswordCredentials( proxyUsername.value, proxyPassword.value ) ) } else { http.credentialsProvider.clear() } } else { http.params.setParameter( ConnRoutePNames.DEFAULT_PROXY, null ) } } updateAuth = { def username = null def password = null if( inlineUrlAuthUsername && inlineUrlAuthPassword ) { username = inlineUrlAuthUsername password = inlineUrlAuthPassword } else if( authUsername.value?.trim() && authPassword.value?.trim() ) { username = authUsername.value password = authPassword.value } if( username && password ) { http.credentialsProvider.setCredentials( new AuthScope( AuthScope.ANY ), new UsernamePasswordCredentials( username, password ) ) } } validateUrl() updateProxy() requestResetValue = 0 sampleResetValue = 0 discardResetValue = 0 failedResetValue = 0 displayRequests = new DelayedFormattedString( '%d', 500, value { requestCounter.get() - requestResetValue } ) displayRunning = new DelayedFormattedString( '%d', 500, value { currentlyRunning } ) displayTotal = new DelayedFormattedString( '%d', 500, value { sampleCounter.get() - sampleResetValue } ) displayQueue = new DelayedFormattedString( '%d', 500, value { queueSize } ) displayDiscarded = new DelayedFormattedString( '%d', 500, value { discardCounter.get() - discardResetValue } ) displayFailed = new DelayedFormattedString( '%d', 500, value { failureCounter.get() - failedResetValue } ) sample = { message, sampleId -> def uri = message['url'] ?: url.value def method = message['method'] ?: method.value def entityBody = message['entityBody'] ?: entityBody.value ?: "" if( uri ) { def httpRequest = new HttpCustom( method, uri ) httpRequest.setEntity(new StringEntity(entityBody, "application/x-www-form-urlencoded", "utf-8")) message['ID'] = method + " " + uri + "?" + entityBody runningSamples.add( httpRequest ) try { def response = http.execute( httpRequest ) message['Status'] = true message['URI'] = uri message['HttpStatus'] = response.statusLine.statusCode if( errorCodeList.value ) { def assertionCodes = errorCodeList.value.split(',') for( code in assertionCodes ) { if( code.trim() == response.statusLine.statusCode.toString() ) { failedRequestCounter.increment() failureCounter.increment() break } } } if( response.entity != null ) { int contentLength = response.entity.contentLength message['Bytes'] = contentLength if( outputBody.value ) message['Response'] = EntityUtils.toString( response.entity ) if( contentLength < 0 ) { if( outputBody.value ) message['Bytes'] = message['Response'].length() else message['Bytes'] = EntityUtils.toString( response.entity ).length() } response.entity.consumeContent() if( !runningSamples.remove( httpRequest ) ) { throw new SampleCancelledException() } return message } } catch( e ) { if( e instanceof SampleCancelledException ) throw e if( e instanceof IOException ) log.warn( "IOException in {}: {}", label, e.message ) else log.error( "Exception in $label:", e ) httpRequest.abort() if ( !runningSamples.remove( httpRequest ) ) { throw new SampleCancelledException() } message['Status'] = false message['Exception'] = e.toString() failedRequestCounter.increment() failureCounter.increment() return message } } else { throw new SampleCancelledException() } } onCancel = { def numberOfRunning = 0 synchronized( runningSamples ) { def methods = runningSamples.toArray() numberOfRunning = methods.size() runningSamples.clear() methods.each { if( !it.aborted ) it.abort() } } return numberOfRunning } onRelease = { ReleasableUtils.releaseAll( displayRunning, displayTotal, displayQueue, displayDiscarded, displayFailed, displayRequests ) } onAction( "RESET" ) { requestResetValue = 0 sampleResetValue = 0 discardResetValue = 0 failedResetValue = 0 } addEventListener( PropertyEvent ) { event -> if ( event.event == PropertyEvent.Event.VALUE ) { if( event.property in [ proxyHost, proxyPort, proxyUsername, proxyPassword, authUsername, authPassword ] ) { http.credentialsProvider.clear() updateProxy() updateAuth() } } } //Layout layout { box( layout:'wrap 2, ins 0' ) { property( property:method, label:'HTTP Method', constraints: 'w 300!, spanx 2') property( property:url, label:'URL', constraints: 'w 300!, spanx 2', style: '-fx-font-size: 17pt' ) property( property:entityBody, label:'HTTP Entity Body', constraints: 'w 300!, spanx 2') runAction = action( label:'Run Once', action: { triggerAction( 'SAMPLE' ) } ) action( label:'Abort Running Pages', action: { triggerAction( 'CANCEL' ) } ) } separator(vertical:true) box( layout:'wrap, ins 0' ){ box( widget:'display', layout:'wrap 3, align right' ) { node( label:'Requests', fString:displayRequests, constraints:'w 50!' ) node( label:'Running', fString:displayRunning, constraints:'w 50!' ) node( label:'Completed', fString:displayTotal, constraints:'w 60!' ) node( label:'Queued', fString:displayQueue, constraints:'w 50!' ) node( label:'Discarded', fString:displayDiscarded, constraints:'w 50!' ) node( label:'Failed', fString:displayFailed, constraints:'w 60!' ) } action( label:'Reset', action: { requestResetValue = requestCounter.get() sampleResetValue = sampleCounter.get() discardResetValue = discardCounter.get() failedResetValue = failureCounter.get() triggerAction('CANCEL') }, constraints:'align right' ) } } //Compact Layout compactLayout { box( widget:'display', layout:'wrap 3, align right' ) { node( label:'Requests', fString:displayRequests, constraints:'w 50!' ) node( label:'Running', fString:displayRunning, constraints:'w 50!' ) node( label:'Completed', fString:displayTotal, constraints:'w 60!' ) node( label:'Queued', fString:displayQueue, constraints:'w 50!' ) node( label:'Discarded', fString:displayDiscarded, constraints:'w 50!' ) node( label:'Failed', fString:displayFailed, constraints:'w 60!' ) } } settings( label: "Basic" ) { property( property: outputBody, label: 'Output Response Body' ) //property( property: propagateSession, label: 'Propagate Session' ) property( property: readResponse, label: 'Read Response' ) property( property: concurrentSamples, label: 'Max Concurrent Requests' ) property( property: maxQueueSize, label: 'Max Queue' ) property( property: errorCodeList, label: 'Error Codes that Count as Failures', constraints:'w 200!') property( property: countDiscarded, label: 'Count Discarded Requests as Failed' ) } settings( label: "Authentication" ) { property( property: authUsername, label: 'Username' ) property( property: authPassword, widget: 'password', label: 'Password' ) } settings( label: "Proxy" ) { property( property: proxyHost, label: 'Proxy Host' ) property( property: proxyPort, label: 'Proxy Port' ) property( property: proxyUsername, label: 'Proxy Username' ) property( property: proxyPassword, widget: 'password', label: 'Proxy Password' ) } scheduleAtFixedRate( { def message = newMessage() Integer.with { message["Requests"] = parseInt( displayRequests.currentValue ) message["Running"] = parseInt( displayRunning.currentValue ) message["Discarded"] = parseInt( displayDiscarded.currentValue ) message["Failed"] = parseInt( displayFailed.currentValue ) message["Queued"] = parseInt( displayQueue.currentValue ) message["Completed"] = parseInt( displayTotal.currentValue ) } send( statisticsOutput, message ) }, 1, 1, TimeUnit.SECONDS ) def statisticsSignature = [ "Requests" : Integer.class, "Running" : Integer.class, "Discarded" : Integer.class, "Failed" : Integer.class, "Queued" : Integer.class, "Completed" : Integer.class ] setSignature( statisticsOutput, statisticsSignature )13 years agoPlace ReadyAPI QuestionsReadyAPI Questions4.3KViews0likes0CommentsError with loadUI-agent on OS X
I did a clean install of loadUI agent 1.5 on Mac OS X, attempted to run the loadUI-agent.command script from Finder, and received the following error: Last login: Thu Aug 18 11:26:16 on ttys000 /Applications/loadUI-Agent/loadUI-agent.command ; exit; djamesml01:~ DJames$ /Applications/loadUI-Agent/loadUI-agent.command ; exit; Launching loadUI Build: loadUI-Dist-2011-06-13-[3] 2011/06/13 20:56 There was an error loading the OSGi configuration! Exiting... logout It seems that the OSGi configuration that's being looked for is not in the directory that the command file was being run from. I was able to modify the command file to change directory to $LOADUI_RUNNER_HOME, then execute the java command. My patch to loadUI-agent.command is as follows: Index: loadUI-agent.command =================================================================== --- loadUI-agent.command (revision 6743) +++ loadUI-agent.command (working copy) @@ -36,4 +36,6 @@ JAVA_OPTS="-Xms128m -Xmx768m -XX:MaxPermSize=128m" +pushd $LOADUI_RUNNER_HOME java $JAVA_OPTS -cp "$LOADUI_RUNNER_CLASSPATH" com.eviware.loadui.launcher.LoadUILauncher -Dloadui.instance=agent -nofx "$@" +popd Also, if I wanted to make contributions to the code base, how would I do that? - Daniel13 years agoPlace ReadyAPI QuestionsReadyAPI Questions2KViews0likes0Comments