In JMeter and BeanShell, how can I make a variable lowercase? - javascript

In JMeter's User Parameters, how can I make a variable lowercase?
Left column
my_lowercase_variable
Right column
${__BeanShell('${my_variable}'.toLowerCase())} //fails
or
${__javaScript('${my_variable}'.toLowerCase())} //fails
Such that ${my_lowercase_variable} is lowercase of ${my_variable}. Tried with quote and without and escaping and such. No luck. Any tricks or tips welcome.

Note to self.
It turns out to be a two liner in BeanShell Sampler rather than a __BeanShell command. Not exactly in the examples unfortunately.
I added the BeanShell Sampler under the Thread Group, then made a variable. No parameters in the form were required only the two liner script below. As long as I don't change the variable I can copy the data to another variable, change that instead, and then make a Value reference to that wherever needed.
First define a variable in some User Parameters or such
ie:
Name: my_initial_reference
Value: ITS IN CAPS
Add a Bean Sampler under the User Preferences or definition list (just next, it's not a child process)
Put in:
String blah = "${my_initial_reference}"; //
vars.put("blah", blah.toLowerCase()); //${blah} = "its in caps" now available
Now under that with Name/Value pairs I can map ${blah} as the value to whatever process name requires it.
Note that the Debug response will still show the initial value in caps but you'll also see blah=its in caps which is what I wanted to use.

Simply can add a function
${__lowercase(${VAL},VALUE)}
${__uppercase(${VAL},VALUE)}
Note: VAL can be correlated or paramiterized value (e.r VAL= TO LOWER or VAL= TO UPPER). We can use this function in beanshell (pre-processor/post-processor/sampler). Jmeter version using (2.6).
Can use it where ever we want in the script as ${VALUE}.

${__javaScript('${foobar}'.toLowerCase())} does work. If the output is ${foobar} instead of desired value, it means that the variable has not been declared
Note that variables are defined only after the "User Defined Variable" component has been parsed. Variables cannot be reused within a single "User Defined Variable" component e.g.:
The second row in that image will not be able to refer to the variable my_variable in the first row. To be able to refer to the first variable, two "User Defined Variable" components is needed. The first variable will be in the first component and the second variable in the second one, e.g.:
With that, ${my_lower_case_variable} will successfully be converted into some value.
${__BeanShell("${my_variable}".toLowerCase())} works too. (Note that Bean Shell requires double quotes. The code in your question uses single quotes.)
Another way is to use vars.get:
${__javaScript(vars.get('my_variable').toLowerCase())}
${__BeanShell(vars.get("my_variable").toLowerCase())}

Hmmmm, your bean shell code didn't work for me. The bean shell sampler returned:
Response code: 500
Response message: org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: ``String blah = AAP; vars.put("blah", blah.toLowerCase()); //${blah} now availab . . . '' : Typed variable declaration : Void initializer
I added two double quotes to solve it:
String blah = "${my_initial_reference}";
vars.put("blah", blah.toLowerCase()); //${blah} now available

The beanshell and JavaScript functions in this use will fail, because they don't import the packages you need in order to use .toLowerCase.
If you really need to use a function to convert case (rather then declaring them as lowercase in the first place), you may need to write a full beanshell post-processor script in order to import the needed packages.
http://jmeter.apache.org/usermanual/functions.html#__BeanShell
http://jmeter.apache.org/usermanual/functions.html#__javaScript
http://www.javadocexamples.com/java_examples/org/apache/jmeter/

var blah = "${my_initial_reference}";
blah.toLowerCase();

Related

GTM - Truncated DataLayer Variable into Custom Javascript Variable

I currently have a dlv variable to store "First Name" (gtm.element.2.value) which is working correctly.
I also a dlv to store "D.O.B." which is also working correctly - gtm.element.5.value (this is formatted MM/DD/YYYY).
However, I'd like to only show the first initial in the First Name dlv and the Year in the DOB dlv. I'm thinking of utilizing a Custom JS variable but am open to ideas if there is an easier route.
Can anyone help provide what that Custom JS variable would look like? I've been searching for some examples but not having luck with this specific example.
Appreciate the help in advance!
To get the first initial (i.e. first character) of the First Name variable, you can indeed use a Custom JavaScript variable with this:
function() {
return {{first_name}}[0]; // Replace with the actual DLV reference
}
Similarly, to get just the year (YYYY) of the D.O.B., you can use a Custom JS variable:
function() {
return {{date_of_birth}}.split('/').pop(); // Replace with the actual DLV reference
}
Obviously you might want to add some checks to make sure the input is in a predictable format. For example, you might want to check that {{first_name}} is a string of non-zero length, and you might want to check that {{date_of_birth}} actually contains a date string with slash as the separator.

Blockly: type check of child blocks during code generation

I am trying to generate code from blocks that can have any input type to JavaScript. But to do so I need to know what type these blocks are during generation time.
Most blocks already have a type internally for the type check
"output": ["Integer","Number"],
or
this.setOutput(true, 'String');
but I can't find a function to access the 'output' field with.
Ideally I want to access the type in the generator function like this:
var return_type = block.getChildren()[0].functionToAccessOutputWith;
There is the '.type' field but that one gives the name of the block type not the return value defined with output.
It seems like a very common problem but I can't find anything online.
Just trace through the source code by following the function calls of Block.setOutput(). It's not that hard. Eventually you will reach a line in Blockly.Connection that says this.check_ = check;
So what you are looking for is basically block.outputConnection.check_. But this is not a function and the _ indicates that it is supposed to be a private property. For convenience I'd write a getter function into Block.

Botpress concatenate variable, as argument, in execute code action form

I know if I pass {{variable}} (like a {{event.text}}) in args field of action form works fine.
But, when I try concatenate this variable with a another String, this not work.
Result in {{state.api_url}}/users string, and I need http//myapi.com/users
Is it possible?
I may have an extremely kludgy workaround for this based on bad javascript.
I was looking to iterate a temp variable downwards. I did the assignment in the raw code box for a transition
Good code like temp.variable==1 would be a true/false test.
But just using one equals sign performs the assignment.
So temp.variable=temp.variable-1 in the raw code box subtracted one from my (numeric value) variable.
This seems to return False for the purposes of the transition so it doesn't matter where you point it as long as it's in the chain.
It seems to work for me, anyway.
I'm properly not sure what your code would look like, perhaps you make a new variable then do a transition with
temp.variable_you_just_made=state.api_url+'/users'
then call that variable doing your url thing?
[Looking around I come to suspect the correct thing would be to make a new action https://botpress.io/docs/10.0/getting_started/trivia_actions/ but I am new to all this]

In JavaScript, how do I get the URL of the JavaScript file, not the location URL?

I would like to use a query string parameter so that way I can specify the name of a DOM element.
I have some code that requires the height of the header and I would like that code to work for any theme. Only at times the header uses the <header> tag, at times it has a specific identifier, at times it is a specific class... to be able to reuse that code over and over again, I'd like to include it in a way such as:
<script src="https://www.example.com/js/my-script.js?c=header"></script>
What I want to be able to do is get the "?c=header" part from that JavaScript URL to send search a DOM object with jQuery(".header"). Do we have a way to know the URL of the JavaScript itself from the JavaScript being executed?
Obviously, I know of window.location.href and that's not the URL I'm looking for.
As mentioned by #Kaiido in a comment, there is the document.currentScript parameter that gives you access to the <script> tag which is currently running. Only there is a small trick to it, that parameter is defined on the first pass, not when executing functions within your script.
So what one can do is save that information, or at least what you need from that object, in the global scope or a static in your object.
In my case, I just did the following:
// Script to tweak things on many websites
var this_script_url = document.currentScript.src;
jQuery(document).ready(function()
{
// at this point: "document.currentScript === null"
var qs = this_script_url.split("?", 2);
if(qs && 2 == qs.length)
{
... // handle qs[1] which is the query string (a=1&b=3&...)
}
});
Please make sure you don't use a global name that's too generic. It should include the name of your script or abbreviation thereof. Otherwise you are likely to clash with another script's global.
Now if you have a prototype object, I would suggest you use a static member instead of a global.
var my_class = {};
my_class.script_url = document.currentScript.src;
// and later you can reference it directly as in:
url = my_class.script_url;
This way you are more likely to avoid clashing problems (the only thing that needs to be changing in case of a clash is the name my_class).
At this point, the ES5 or ES6 class keyword does not offer you to create variables.

Pass multiple values with onClick in HTML link

Hi Im trying to pass multiple values with the HTML onclick function. Im using Javascript to create the Table
var user = element.UserName;
var valuationId = element.ValuationId;
$('#ValuationAssignedTable').append('<tr> <td>Re-Assign </td> </tr>');
But in my Javascript function the userName is undefined and the valuationId is a string with the valuationId and the UserName combined
function ReAssign(valautionId, userName) {
valautionId;
userName;
}
If valuationId and user are JavaScript variables, and the source code is plain static HTML, not generated by any means, you should try:
Re-Assign
If they are generated from PHP, and they contain string values, use the escaped quoting around each variables like this:
<?php
echo 'Re-Assign';
?>
The logic is similar to the updated code in the question, which generates code using JavaScript (maybe using jQuery?): don't forget to apply the escaped quotes to each variable:
var user = element.UserName;
var valuationId = element.ValuationId;
$('#ValuationAssignedTable').append('<tr> <td>Re-Assign </td> </tr>');
The moral of the story is
'someString(\''+'otherString'+','+'yetAnotherString'+'\')'
Will get evaluated as:
someString('otherString,yetAnotherString');
Whereas you would need:
someString('otherString','yetAnotherString');
Solution: Pass multiple arguments with onclick for html generated in JS
For html generated in JS , do as below (we are using single quote as
string wrapper).
Each argument has to wrapped in a single quote else
all of yours argument will be considered as a single argument like
functionName('a,b') , now its a single argument with value a,b.
We have to use string escape character backslash() to close first argument
with single quote, give a separator comma in between and then start next argument with a
single quote. (This is the magic code to use '\',\'')
Example:
$('#ValuationAssignedTable').append('<tr> <td>Re-Assign </td> </tr>');
$Name= "'".$row['Name']."'";
$Val1= "'".$row['Val1']."'";
$Year= "'".$row['Year']."'";
$Month="'".$row['Month']."'";
echo '<button type="button" onclick="fun('.$Id.','.$Val1.','.$Year.','.$Month.','.$Id.');" >submit</button>';
enclose each argument with backticks( ` )
example:
<button onclick="updateById(`id`, `name`)">update</button>
function updateById(id, name) {
alert(id + name );
...
}
Please try this
for static values--onclick="return ReAssign('valuationId','user')"
for dynamic values--onclick="return ReAssign(valuationId,user)"
That is because you pass string to the function. Just remove quotes and pass real values:
Re-Assign
Guess the ReAssign function should return true or false.
A few things here...
If you want to call a function when the onclick event happens, you'll just want the function name plus the parameters.
Then if your parameters are a variable (which they look like they are), then you won't want quotes around them. Not only that, but if these are global variables, you'll want to add in "window." before that, because that's the object that holds all global variables.
Lastly, if these parameters aren't variables, you'll want to exclude the slashes to escape those characters. Since the value of onclick is wrapped by double quotes, single quotes won't be an issue. So your answer will look like this...
Re-Assign
There are a few extra things to note here, if you want more than a quick solution.
You looked like you were trying to use the + operator to combine strings in HTML. HTML is a scripting language, so when you're writing it, the whole thing is just a string itself. You can just skip these from now on, because it's not code your browser will be running (just a whole bunch of stuff, and anything that already exists is what has special meaning by the browser).
Next, you're using an anchor tag/link that doesn't actually take the user to another website, just runs some code. I'd use something else other than an anchor tag, with the appropriate CSS to format it to look the way you want. It really depends on the setting, but in many cases, a span tag will do. Give it a class (like class="runjs") and have a rule of CSS for that. To get it to imitate a link's behavior, use this:
.runjs {
cursor: pointer;
text-decoration: underline;
color: blue;
}
This lets you leave out the href attribute which you weren't using anyways.
Last, you probably want to use JavaScript to set the value of this link's onclick attribute instead of hand writing it. It keeps your page cleaner by keeping the code of your page separate from what the structure of your page. In your class, you could change all these links like this...
var links = document.getElementsByClassName('runjs');
for(var i = 0; i < links.length; i++)
links[i].onclick = function() { ReAssign('valuationId', window.user); };
While this won't work in some older browsers (because of the getElementsByClassName method), it's just three lines and does exactly what you're looking for. Each of these links has an anonymous function tied to them meaning they don't have any variable tied to them except that tag's onclick value. Plus if you wanted to, you could include more lines of code this way, all grouped up in one tidy location.
function ReAssign(valautionId, userName) {
var valautionId
var userName
alert(valautionId);
alert(userName);
}
Re-Assign

Categories

Resources