I am writing a custom rule regarding raising the issue if some keyword is not found in the file and that too I want to check on only one js file, not on all js files. Is there any way to pass filename on which I want to check rule specifically and raise the issue?
The easiest way would be to test the filename in your rule implementation, you can do something like this in your rule
#Override
public List<Issue> scanFile(TreeVisitorContext context) {
JavaScriptFile jsFile = context.getJavaScriptFile();
if (jsFile.fileName().equals("file.js")) {
addIssue(context.getTopTree(), "Issue on specific file.");
}
return super.scanFile(context);
}
Related
I am using csv file for posting the data and checking the response back, where in find text, i want to use the same csv files.
In string body im using :{{DataSource1.Table#csv.objectId}} which is working fine for posting request.
same thing i passed in find text in validation rule, it doesn't work and i am getting failure for this validation rule.
In validation rule, i am using "Find Text" and passing {{DataSource1.Table#csv.objectId}}
The "Details" tab show this for the validation rule :
Find Text Validation The required text '{{DataSource1.Table#csv.objectId}}' did not appear in the HTML response. FindText={{DataSource1.Table#csv.objectId}}, IgnoreCase=True, UseRegularExpression=True, PassIfTextFound=True
Tried using custom validation rule and tried passing context parameter.Same issue.Validation rule for it is below:
Many places where a ".webtest" allows a context parameter (CP) have a "bind" facility on the property. For example, look at the Value property of a "Header" to a request, it has a drop-down list giving access to CPs.
Some properties of a ".webtest" allow CPs to be embedded in the text. For example the Url property of a request allows things like text{{CpOne}}moretext{{CpTwo}}etc.
Unfortunately there are some properties of a ".webtest" that only allow text and do not expand embedded CPs. I have not found any clear statement of which places allow bound CPs, which support embedded CPs and which allow neither. Also I have not found any built in support for CPs in user-written plugins or extraction rules or validation rules. My approach has been to try using CPs wherever I need them and, when they do not work, write my own code that does what is needed.
You might write your own validation rule as described in this Microsoft page. The code could be based on the following code which has not been tested.
public class FindCpValueInResponseBody : ValidateResponseUrl
{
public string CpWithTextToFind { get; set; }
public override void Validate(object sender, ValidationEventArgs e)
{
string TextToFind = e.WebTest.Context[CpWithTextToFind].ToString();
e.WebTest.AddCommentToResult("Looking for '" + TextToFind +"' (from CP '" + CpWithTextToFind + "').");
if (e.Response.BodyString.Contains(TextToFind))
{
e.IsValid = true;
e.Message = "Text '" + TextToFind + "' found.";
}
else
{
e.IsValid = false;
e.Message = "Text '" + TextToFind + "' not found.";
}
}
}
It should be a simple matter to enhance the above method to add the other properties of the built-in FindText validation rule; properties such as Pass if text found and Ignore case etc, should they be needed.
The above validation rule takes the context parameter name. So if the value is from a data source then the value should be something like DataSource1.Table#csv.objectId. Note that there are no curly braces (i.e. no { or }) and no leading or trailing whitespace.
I'm trying to use ASP.Nets BundleTable to optomize some javascript files, but have run into a problem where a specific addon (jQuery-Timepicker) fails to work when the code has been minified. See here.
Bundle code is currently similar to:
// Add our commonBundle
var commonBundle= new Bundle("~/CommonJS" + culture.ToString());
// JQuery and related entries.
commonBundle.Include("~/Scripts/jquery-1.7.2.js");
commonBundle.Include("~/Scripts/jquery-ui-1.8.22.js");
commonBundle.Include("~/Scripts/jquery.cookie.js");
commonBundle.Include("~/Scripts/jquery-ui/jquery-ui-timepicker-addon.js"); // This is the one that does not work when bundled
// JS Transformer
commonBundle.Transforms.Add(new JsMinify());
BundleTable.Bundles.Add(commonBundle);
If I remove the jquery-ui-timepicker-addon.js file, then include it separate in my webpage, then it works properly. (Otherwise I get the Uncaught TypeError: undefined is not a function error).
I'm wondering if I can somehow setup my bundling code to skip minifying this one file (but still have it included in the bundle)? I've been looking around but have not come up with any solutions for doing so.
So the issue is that all the files are bundled together, and then the entire bundle is minimized. As a result you aren't going to easily be able to skip minification of just one file. Probably the best way to do this would be to create a new Transform that appended the contents of this file you want unminified. Then you would append this Transform to your registered ScriptBundle:
commonBundle.Transforms.Add(new AppendFileTransform(""~/Scripts/jquery-ui/jquery-ui-timepicker-addon.js""));
AppendFileTransform would simply append the contents of the file to the bundled response. You would no longer include the timepicker in the bundle explicitly, but instead this transform would be including it, and this would effectively give you the behavior you are looking since the JsMinify transform would run first and minify the bundle, and then you would add the file you want at the end unminified.
This can be solved better from the other direction - instead of trying to not minify a single file, add transforms for individual items instead.
First - create a class that implements IItemTransform and uses the same code to minify the given input:
public class JsItemMinify : System.Web.Optimization.IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
var min = new Microsoft.Ajax.Utilities.Minifier();
var result = min.MinifyJavaScript(input);
if (min.ErrorList.Count > 0)
return "/*minification failed*/" + input;
return result;
}
}
Second - add this item transform to the individual files and remove the bundle transform:
var commonBundle= new Bundle("~/CommonJS");
// the first two includes will be minified
commonBundle.Include("~/Scripts/jquery-1.7.2.js", new JsItemMinify());
commonBundle.Include("~/Scripts/jquery-ui-1.8.22.js", new JsItemMinify());
// this one will not
commonBundle.Include("~/Scripts/jquery.cookie.js");
// Remove the default JsMinify bundle transform
commonBundle.Transforms.Clear();
BundleTable.Bundles.Add(commonBundle);
You cannot setup Bundle to skip minifying certain files and to minify rest of the files.
You could implement your own Bundle or Transform by overriding Bundle.ApplyTransform or JsMinify.Process methods, but you would need to take care not to break change-tracking of files, key generation, cache invalidation, etc... (or doing some ugly hack). It's not worth the effort.
I would keep separate js file, as you already mentioned.
This is just complete example based on Hao Kung's answer
var myBundle = new ScriptBundle("~/bundles/myBundle").Include(
"~/Scripts/script1.js",
"~/Scripts/script2.js",
);
myBundle.Transforms.Add(new AppendFileTransform("~/Scripts/excludedFile.min.js"));
bundles.Add(myBundle);
And here is example implementation of the AppendFileTransform:
public class AppendFileTransform : IBundleTransform
{
private readonly string _filePath;
public AppendFileTransform(string filePath)
{
_filePath = filePath;
}
public void Process(BundleContext context, BundleResponse response)
{
response.Content += File.ReadAllText(context.HttpContext.Server.MapPath(_filePath));
}
}
I'm managing an MVC3 app where I need to support the ability of 3rd parties to create link to assets within my domain. Because some of the links are sliced and diced by mail merges and other text editing problems, URLs with typos have been introduced, e.g.:
/Content/ima!+ges/email/spacer.gif
or
/Content/image++s/email+/spacer.gif
I'd like to strip these extraneous characters by RegEx before attempting to serve them. I _think this is something a Route method could accomplish and I'd welcome a pointer or two to articles that demonstrate this approach.
ADDENDUM (cuz I need the formatting):
Implementing #Nathan's routing I'm unable to send the filename to the controller handler - it's always seeing a null value passed in. I've tried both 'filepath' and 'path' with the same 'null' result.
routes.MapRoute(
"MangledFilename",
"{*filepath}",
new { controller = "MangledFilename", action = "ServeFile" }
);
I think this is a matter of configuring wildcard handling on IISExpress and am looking for that solution separately. The more serious immediate problem is how your suggestion returns the HttpNotFound - i'm getting a hard IIS exception (execution halts with a YellowScreenDeath) instead of the silent 404 result.
public ActionResult ServeFile(string filePath)
{
if (filePath != null) // workaround the null
{
...
}
return HttpNotFound();
}
thx
I think something along this approach should work:
First add a route like this to the end of your route registering declarations:
routes.MapRoute(
"MangledFilename",
"{*filepath}",
new { controller = "MangledFilename", action = "ServeFile" });
If you haven't seen them before, a route parameter with an * after the opening { is a wildcard parameter, in this case it will match the entire path. You could also write it like content/{*filepath} if you wanted to restrict this behavior to your content directory.
And then a controller something like this should do the trick:
public class MangledFilenameController : Controller
{
public ActionResult ServeFile(string filePath)
{
filePath = CleanFilePath(filePath);
var absolutePath = Server.MapPath(filePath);
if (System.IO.File.Exists(absolutePath))
{
var extension = System.IO.Path.GetExtension(absolutePath);
var contentType = GetContentTypeForExtenion(extension);
return File(absolutePath, contentType);
}
return HttpNotFound();
}
private string CleanFilePath(string filepath)
{
//clean the path up
return filepath;
}
private string GetContentTypeForExtenion(string extension)
{
//you will want code here to map extensions to content types
return "image/gif";
}
}
In regards to mapping an extension to a MIME / content type for the GetContentTypeForExtension method, you could choose to hard code types you are expecting to serve, or use one of the solutions detailed in this post:
File extensions and MIME Types in .NET
EDIT:
After thinking about it, I realized there's another way you can handle the ServeFile action. Redirecting to the existing file could be simpler. I'm leaving the original method I wrote above and adding the alternative one here:
public ActionResult ServeFile(string filePath)
{
filePath = CleanFilePath(filePath);
var absolutePath = Server.MapPath(filePath);
if (System.IO.File.Exists(absolutePath))
{
return RedirectPermanent(filePath);
}
return HttpNotFound();
}
I believe #Nathan Anderson provided a good answer but it seems incomplete.
If you want to correct the typos and the types are as simple as those you mentioned then you can use Nathan code but before trying to find the file, you remove any plus or exclamation point characters in the path and you can do it like this:
String sourcestring = "source string to match with pattern";
String matchpattern = #"[+!]";
String replacementpattern = #"";
Console.WriteLine(Regex.Replace(sourcestring,matchpattern,replacementpattern));
Generated this code from the My Regex Tester tool.
This is the code you need. This code also removes any + character from the filename. If you don't want that behavior, you may select a substring without the filename and only replace + and ! characters before the filename.
I have a RESTful api using Jersey right now, and am converting it to be OData standard compliant. There are a few things I have not converted yet, but will get there, and is not important at this moment. One of the things I need to convert that is important is the key path params. Odata has the standard of making the key wrapped in parenthesis. So in this example myapi.com/product(1) - is the OData call to get a product whose id is 1. Currently that is possible in my system with this myapi.com/product/1
When I add the parenthesis to the path parameter I get a 404 error. My class level path is #Path("/product") and my method level path is #Path("({id})"), and use to be #Path("/{id}"). I've tried adding the parenthesis as part of the variable planning to strip them off in the method, and I've tried formatting the id with some regex #Path("{id : regex stuff}"), and neither works.
If I make my method path parameter like this #Path"/({id})") - so the call is myapi.com/product/(1), it works fine. The parenthesis is not the issue obviously. It seems the Jersey splits the uri into chunks using the forward slashes for the routing, and sense there is no forward slash between the id an root resource name, then nothing is found. It makes sense.
Is there a way to change Jerseys method of matching uri strings with some regex or something? Has anyone used Jersey with Odata? I would rather not use odata4j just for the resolution to this issue, it seems like there should be a way to get this to work.
What I did:
Based on Pavel Bucek's answer I did implement a ContainrRequestFilter independently to the filter I use for security. In my case I didn't look to see if existed, I just tried to do the replace.
try
{
String uriString = request.getRequestUri().toString();
uriString = uriString.replaceAll("(\(|\)\/?)", "/");
request.setUris(request.getBaseUri(), new URI(uriString));
} catch (final Exception e)
{
}
return request;
I think that the easiest way how to handle this "protocol" would be introducing ContainerRequestFilter, which would replace "()$" with "/$" in the incoming URI. So you will be able to serve OData and standard REST request in one app.
See http://jersey.java.net/nonav/apidocs/1.11/jersey/com/sun/jersey/spi/container/ContainerRequestFilter.html
Simple filter I used to test this case:
rc.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, new ContainerRequestFilter() {
#Override
public ContainerRequest filter(ContainerRequest request) {
try {
if(request.getRequestUri().toString().endsWith("(1)")) {
request.setUris(
request.getBaseUri(),
new URI(request.getRequestUri().toString().replace("(1)", "/1")));
}
} catch (Exception e) {
}
return request;
}
});
both
curl "http://localhost:9998/helloworld(1)"
curl "http://localhost:9998/helloworld/1"
hit same Resource method now. (Obviously you'll need to improve current filter to be able to handle various values, but it should work for you).
I'm running into a "bad request" error when playing back a test. I've tracked it down to a comma and space in a button that has "Yes, Do" as its value. There is functionality in another page that runs based on this value. When I remove the comma and space in the both pages everything works perfectly. I've tried toggling the 'url encode' property for that field in the Web Perf Test to true, but it still fails. When I look at the details of the request it shows "Yes,+Do" as the querystring param. I can't change the control value in this situation. Any hints?
It seems odd that the value of a button is being passed as a query string parameter in the first place...
Is it set up where there is an extraction rule from a prior request and then that context parameter is used for a later request? If so, you can actually modify the value. You can either hard code the value in the later request, or if you still need to get it dynamically but just modify it, you can create a pretty simple plugin. Sample code for it would be:
public class StringCharsFromParam: WebTestRequestPlugin
{
public override void PreRequest(object sender, PreRequestEventArgs e)
{
string ExtractParam = ((string)e.WebTest.Context["NameOfContextParameter"]);
if (ExtractParam != null && ExtractParam.Contains(", ")
{
e.WebTest.Context["NameOfContextParameter"] = ExtractParam.Replace(", ", "");
}
}
}
You would then add this WebTestRequestPlugin to your WebTest.