Fitnesse smartrics.rest.fitnesse.fixture.RestFixture.setBaseUrl - rest

I have a requirement for a test to make a call to one REST endpoint that generates a security token then make a second to the actual system under test. In order to do this I am using smartrics.rest.fitnesse.fixture.RestFixture and setting the baseurl in instantiation to the first base. I am trying to make this call and then set the new baseurl to the new location but am having trouble doing so.
It appears from perusing the code that there is a method setBaseUrl(Url url) but I cannot find an example of using this and am failing trying to figure it out myself.
Has anyone had any luck with this or is there another, better/easier way to achieve this?

The problem lies in RestFixture:processRow - since it uses Java reflection, it attempts to call method without parameters. This will fail since setBaseUrl accepts one argument (Url). I have tried one modification, though not the best way to achieve it - current code RestFixture v3.0 (RestFixture.processRow()):
method1 = getClass().getMethod(methodName);
method1.invoke(this);
Modified code in RestFixture.processRow():
Method[] methods = getClass().getMethods();
int i = 0;
for(i = 0; i < methods.length; i++){
if(methodName.equals(methods[i].getName())){
method1 = methods[i];
break;
}
}
Class[] paramTypes = method1.getParameterTypes();
List<Object> params = new ArrayList<Object>();
for(i = 0; i < paramTypes.length; i++){
String cellText = row.getCell(i+1).text();
Object param = paramTypes[i].getConstructor(String.class).newInstance(cellText);
params.add(param);
}
method1.invoke(this, params.toArray());
Once this modification is done (you might need to add required imports - java.lang.InstantiationException, java.lang.Object, java.util.ArrayList; and an exception handler for InstantiationException), re-build the RestFixture and that should work.

We had what sounds like a similar requirement - we needed to use RestFixture(POST) to retrieve a URL for use in a subsequent RestFixture call(GET).
(Note that we're using an ancient RestFixture 1.1)
I modified the processArguments() method in RestFixture.java thus:
// baseUrl = new Url(args[0]); // original line
baseUrl = new Url(resolve(args[0])); // modified
With this modification in place, my Fitnesse test looks like this:
`!| RestFixture | http:///fds |
| setBody |{"param1":"blah","param2":"blather"} |
| POST | /GetThatUrl | 200 | | |
| let | $urlresult | body | |
!| RestFixture | $urlresult |
| GET| | 200 | Content-Length:[\d]+ | ||`
Without the code change, $urlresult was not resolved and I could not pass in the URL as a variable.

Related

iText7: Allow ListItem to flow horizontal next to each other

I'm looking for a way to have up to 3 list items next to each other. I've seen similar question with text blocks in the past with the recommendation to use Table as future proof mechanism. This isn't possible in my case, because accessibility requires me to use the semantic correct element.
Visual example:
# Fruits
| 1. Apple | 2. Banana | 3. ...
| 4. ... | 5. ...
I tried the following and some neaunces of it:
List list = new List();
list.setWidth(UnitValue.createPercentValue(100));
var listItem1 = new ListItem("Apple");
listItem1.setWidth(UnitValue.createPercentValue(30));
listItem1.setKeepTogether(true);
listItem1.setHorizontalAlignment(HorizontalAlignment.LEFT);
listItem1.setVerticalAlignment(VerticalAlignment.TOP);
list.add(listItem1);
var listItem2 = new ListItem("Banana");
listItem2.setWidth(UnitValue.createPercentValue(30));
listItem2.setKeepTogether(true);
listItem2.setHorizontalAlignment(HorizontalAlignment.CENTER);
listItem2.setVerticalAlignment(VerticalAlignment.TOP);
list.add(listItem2);
var listItem3 = new ListItem("...");
listItem3.setWidth(UnitValue.createPercentValue(30));
listItem3.setKeepTogether(true);
listItem3.setHorizontalAlignment(HorizontalAlignment.RIGHT);
listItem3.setVerticalAlignment(VerticalAlignment.TOP);
list.add(listItem3);
document.add(list);

How to use NSEventMask with Swift

Why am I getting a compiler error indicating the boolean OR function "|" cannot be used with in the following manner:
localEvent = self.window.nextEventMatchingMask(NSEventMask.LeftMouseUpMask | NSEventMask.LeftMouseDraggedMask)
EDIT:
Here is what I eventually found to work
localEvent = self.window!.nextEventMatchingMask(Int(NSEventMask.LeftMouseUpMask.rawValue | NSEventMask.LeftMouseDraggedMask.rawValue))!
Try like this:
localEvent = window.nextEventMatchingMask(Int(NSEventMask.LeftMouseUpMask.rawValue))
or
localEvent = window.nextEventMatchingMask(
Int(NSEventMask.LeftMouseUpMask.union(.LeftMouseDraggedMask).rawValue))

Unable to set a global variable

I want to use a function and the parameter I am passing should be set to global all the time. How can I do that? Here is my code:
function ReadExcelfunction($FileName,$SheetName,$RowNum,$ColNum,$Parameter)
{
var $excel = _getExcel($FileName,$SheetName);
var $excelData=$excel.getData();
var $Parameter=$excelData[$RowNum][$ColNum];
//_setGlobal($Parameter,$excelData[$RowNum][$ColNum]) -- Commented
}
Now suppose I pass the parameters as -- File sheet 1 1 Name.
What I want is this: name with the Value is stored as Global value.
Earlier I used _setGlobal($Parameter,$excelData[$RowNum][$ColNum]) which solved the purpose but this API has been removed and now I need to change my script.
I am using the sahi scripting language which is similar to JavaScript.
You don't need to use _setGlobal, you only need to declare a var before the function declaration. For example, you can declare a new Array and then set/get values just like _setGlobal.
// www.google.com used as start URL
var $globalVariable = new Array();
function SetGlobalVariable(key, newValue) {
$globalVariable[key] = newValue;
}
SetGlobalVariable('inputValue', 'stack overflow');
_setValue(_textbox("q"), $globalVariable['inputValue']);
A probable solution for you is to write value to an existing excel sheet cell from the sahi script on the fly and then retrieve the same value from the corresponding cell of excel sheet from another sahi script.
I have done a similar thing using a simple text file.
First File
\\ script 1
var $str = "Hello World";
var$filePath = "C:\\temp\\mystring.txt";
_writeToFile($str, $filePath);
Second File
\\ script 2
var $filePath = "C:\\temp\\mystring.txt";
var $mystr = _readFile($filePath);
Edit: Extended Answer
--------------------------------
| VariableName | VariableValue |
--------------------------------
| MyVar1 | MyVar1Value |
--------------------------------
| MyVar2 | MyVar2Value |
--------------------------------
| MyVar3 | MyVar3Value |
--------------------------------
Create a Sahi Function to creating a new excel sheet:
function _createExcelFile($fileName, $sheetName){
if($sheetName == null || $sheetName == ""){
$sheetName = "Sheet1";
}
_debug("Excel File Name :: " + $fileName);
_debug("Excel File Sheet Name :: " + $sheetName);
var $excelPoi = new Packages.net.sf.sahi.util.ExcelPOI($fileName, $sheetName);
$excelPoi.createNew();
}
Further you can refer the _getExcel($filePath[, $sheetName]) API from Sahi Pro. You need to do some iterations to get things done. You can read and write data as required.
Note: I have tried this only in the latest version of Sahi Pro i.e. 6.1.0.

How do I force Catalyst::Controller::REST to render a view following a POST request, if no content type was specified?

I am hacking together a RESTful server in Catalyst. Although this is nominally a strict RESTful service, I don't really care about the caller's accepted response types, I always want it to be XML rendered by Template Toolkit; so I have my own view class (based on Catalyst::View::TT) with a 'process' method that just sets the content-type and calls the superclass:
sub process {
my ( $self, $c ) = #_;
$c->response->content_type('text/xml; charset=utf-8');
$self->SUPER::process($c);
}
This view class also has a line in the config block, "TEMPLATE_EXTENSION => '.tt2'", which I assume is how Catalyst knows that when I say something like $c->stash->{template} = 'world/view.tt2' then the .tt2 extension means that it should use this class (otherwise I'm not sure how Catalyst ever knows what view class to use).
I also have a 'RenderView' ActionClass on the end action, to override the default REST controller behavior (which delegates to whatever serializer matches the caller's accepted response types) and instead fall through to the default view. This just looks like sub end : ActionClass('RenderView') { }
When I test this with GET, I see the process method appearing at the end of the action chain, and the view renders correctly:
.------------------------------------------------------------+-----------.
| Action | Time |
+------------------------------------------------------------+-----------+
| /world/begin | 0.000123s |
| /auto | 0.000139s |
| /world/world_id | 0.268140s |
| /world/view | 0.259048s |
| /world/view_end | 0.000083s |
| /view_end_GET | 0.110241s |
| /world/end | 0.049207s |
| -> Zoo::View::XML->process | 0.048564s |
'------------------------------------------------------------+-----------'
However, my POST requests don't seem to be rendering the view: by default I get a Content-type unsupported... error message instead of the body I want, along with a 415 UNSUPPORTED error code, even though I have set $c->stash->{template}. Note the lack of a call to Zoo::View::XML->process at the end of the POST request's action chain:
.------------------------------------------------------------+-----------.
| Action | Time |
+------------------------------------------------------------+-----------+
| /world/begin | 0.030158s |
| /auto | 0.000116s |
| /world/world_id | 0.001228s |
| /world/lock | 0.000915s |
| /world/lock_end | 0.000049s |
| /lock_end_POST | 0.809860s |
| /world/end | 0.000279s |
'------------------------------------------------------------+-----------'
Digging deeper, it looks like the RenderView action will silently bail if $c->response->body is already set, which (by inserting warn messages) I figured out that it seems to be for the POST request (where the body is set to the "Content-type unsupported" error message by the time it reaches my lock_end subroutine) but not the GET request (for which $c->response->body remains undefined).
Anyone happen to know why POST is being picky about the response type, while GET is not? How can I tell POST to stop worrying about the requested content-type (or lack of it)? By looking at the Catalyst::Controller::REST documentation it seems like maybe I need to specify a default deserializer which just does nothing? But how exactly?
Thanking you for your help....
Adding __PACKAGE__->config(default => 'text/xml'); to my controller class seemed to do the trick.

Selenium IDE - always fail on any 500 error

Is there an easy way to tell Selenium IDE that any action that results in a http 500 response means the test failed?
I have tests that are 75 page requests long. Sometimes, I get a crash and burn somewhere in the middle, but the tests come back green.
Taking a look at selenium-api.js, I saw that there is a parameter ignoreResponseCode in the signature of the doOpen method in selenium-api.js :
Selenium.prototype.doOpen = function(url, ignoreResponseCode) {
This parameter is used by the browserbot object :
if (!((self.xhrResponseCode >= 200 && self.xhrResponseCode <= 399) || self.xhrResponseCode == 0)) {
// TODO: for IE status like: 12002, 12007, ... provide corresponding statusText messages also.
LOG.error("XHR failed with message " + self.xhrStatusText);
e = "XHR ERROR: URL = " + self.xhrOpenLocation + " Response_Code = " + self.xhrResponseCode + " Error_Message = " + self.xhrStatusText;
self.abortXhr = false;
self.isXhrSent = false;
self.isXhrDone = false;
self.xhrResponseCode = null;
self.xhrStatusText = null;
throw new SeleniumError(e);
}
I've tried calling the open function from selenium IDE with value = false and this results in an error (test failed).
My PHP test page was :
<?php
header('HTTP/1.1 500 Simulated 500 error');
?>
And this results in :
For me, this solves the problem of checking HTTP response status.
Make a JavaScript file called "user-extensions.js" and add it to the Selenium-IDE under Options > Options. If you are running Selenium RC, pass it into the parameter when starting up your server in the jar command. There should be a user extensions javascript file attribute.
Then close and restart Selenium-IDE. The User-Extensions file is cached when the IDE starts up.
Add this code to your Selenium user-extensions.js file to make a custom command called "AssertLocationPart". As you know "assertLocation" and "storeLocation" are standard commands. I tried to reduce the extra line of code to storeLocation just by getting the href in the custom function. I wasn't able to get the doAssertValue command to work. I'll have to post my own question for that. That's why it's commented out. For now, just use "this.doStore" instead. And add an extra line to your script after your custom AssertLocationPart command. Since we're not actually doing an assertion in the custom function/command, we should call it "storeLocationPart" (function would be named "doStoreLocationPart"), not "assertLocationPart" (function would be named "doAssertLocationPart"), and just pass in the first parameter. But if you can get the doAssert* to work, please let me know. I'll mess with it another day since I need to do this same thing for work.
Selenium.prototype.doAssertLocationPart = function(partName,assertTo) {
var uri = selenium.browserbot.getCurrentWindow().document.location.href;
//alert("URI = " + uri);
var partValue = parseUri(uri,partName);
//alert("Part '" + partName + "' = " + partValue);
//this.doAssertValue(partValue,assertTo);
this.doStore(partValue,"var_"+partName);
};
// Slightly modified function based on author's original:
// http://badassery.blogspot.com/2007/02/parseuri-split-urls-in-javascript.html
//
// parseUri JS v0.1, by Steven Levithan (http://badassery.blogspot.com)
// Splits any well-formed URI into the following parts (all are optional):
//
// - source (since the exec() method returns backreference 0 [i.e., the entire match] as key 0, we might as well use it)
// - protocol (scheme)
// - authority (includes both the domain and port)
// - domain (part of the authority; can be an IP address)
// - port (part of the authority)
// - path (includes both the directory path and filename)
// - directoryPath (part of the path; supports directories with periods, and without a trailing backslash)
// - fileName (part of the path)
// - query (does not include the leading question mark)
// - anchor (fragment)
//
function parseUri(sourceUri,partName){
var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"];
var uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)?((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri);
var uri = {};
for(var i = 0; i < 10; i++){
uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
if (uriPartNames[i] == partName) {
return uri[uriPartNames[i]]; // line added by MacGyver
}
}
// Always end directoryPath with a trailing backslash if a path was present in the source URI
// Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key
if(uri.directoryPath.length > 0){
uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
if (partName == "directoryPath") {
return uri.directoryPath; // line added by MacGyver
}
}
return uri;
}
Then add this to your web.config file and make sure customErrors is turned off. Since you have a 500 error, it will redirect the user to the default page. Feel free to add a custom page for a 500 HTTP status code if you want to be specific in your Selenium scripts.
<customErrors mode="On" defaultRedirect="/ErrorHandler.aspx">
<error statusCode="401" redirect="/AccessDenied.aspx" />
<error statusCode="403" redirect="/AccessDenied.aspx" />
<error statusCode="404" redirect="/PageNotFound.aspx" />
</customErrors>
This is what your commands will look like in the IDE:
Make sure you're on this page (or something similar) before running the script:
https://localhost/ErrorHandler.aspx?aspxerrorpath=/path/pathyouweretryingtoviewinwebapp.aspx
Log shows that it passed!
[info] Executing: |storeLocation | var_URI | |
[info] Executing: |echo | ${var_URI} | |
[info] echo: https://localhost/ErrorHandler.aspx?aspxerrorpath=//path/pathyouweretryingtoviewinwebapp.aspx
[info] Executing: |assertLocationPart | fileName | ErrorHandler.aspx |
[info] Executing: |assertExpression | ${var_fileName} | ErrorHandler.aspx |
Using the error handler from my previous answer:
Command: assertLocation
Target: regexp:^(https://localhost/ErrorHandler.aspx).*$
Or (per your comment) it's inverse if you don't have error handling turned on, use AssertNotLocation. This may require more work on the person writing the scripts. You'd have to keep track of all pages.
More on pattern matching:
http://seleniumhq.org/docs/02_selenium_ide.html#matching-text-patterns
http://www.codediesel.com/testing/selenium-ide-pattern-matching/