Beanshell function gets called before if/else evaluation - jmeter

I have created 2 BeanShell functions myFoo1 and myFoo2.
The first func should be executed with certain condition and the second function in different condition
The trouble is that in my JSR223Post Processor or BeanPost Processor
String code = ctx.getPreviousResult().getResponseCode();
if (code.contains("200") && (vars.get("abc1") != "Howdee")) {
${__BeanShell(myFoo1("print this"))}
}
else {
${__BeanShell(myFoo2("print this"))}
}
The problem is the beanShell functins myFoo1 and myFoo2 get called before the if/else evaluation.
In another words myFoo1 and myFoo2 they both get called one after another and if/else never has any effect, so it looks like Bean function calls are executed before any evaluation.
How do I get around that?

Remove ${__BeanShell( from the script and call it directly as myFoo2("print this):
String code = ctx.getPreviousResult().getResponseCode();
if (code.contains("200") && (vars.get("abc1") != "Howdee")) {
myFoo1("print this);
}
else {
myFoo2("print this);
}

Related

I want to use assertion for the checkbox

I want to use assertion for this checkbox. It depends on duration. If it's checked duration = forever, if not = a month.
cy.wrap(cy.get('span.ant-checkbox').should('have.class','ant-checkbox-checked')).then((a) => {
if a == true {
cy.log('Forever')
}
})
A few thoughts:
You don't need to cy.wrap() your entire statement. cy.wrap() would primarily be used to wrap a JQuery yielded from cy.get() or a similar command, and insert it back into the Cypress command chain.
Your assertion that the element has a certain class will fail and stop your test before even getting to the .then() part of the command if the element does not have the ant-checkbox-checked class.
Instead, if we get the element, we can use JQuery functions (in this case, .hasClass())to determine if it has the class we want.
cy.get('span.ant-checkbox').then(($el) => {
// cy.get yields a JQuery<HTMLElement>
if ($el.hasClass('ant-checkbox-checked')) {
cy.log('Forever');
} else {
cy.log('A month');
}
});

`withTimeout` with optional timeout behavior

Suppose I'm writing a helper function which supports both the "normal" and "timeout" behavior for a specified block: if the timeMillis parameter is null, then run the block normally, and otherwise, run it from within a withTimeout call.
I've come up with this implementation which looks dubious to me:
suspend fun <T> withOptionalTimeout(timeMillis: Long?, block: suspend CoroutineScope.() -> T): T {
if (timeMillis == null) {
return block(CoroutineScope(currentCoroutineContext()))
}
return withTimeout(timeMillis, block)
}
What is the correct way to implement this function?
What is the correct way to implement this function as inline one?

Jmeter - How to keep trying the same request until it succeeds

So right now I have my http request under a while controller and I have a user defined variable Failure set to true. I would like jmeter to keep trying this request until it succeeded (without returned 500).
My while loop condition is:
${__javaScript(${Failure})}
I also tried ${Failure} as while condition but getting the same result.
And I have a JSR223 Assertion after the result tree as following:
if (ResponseCode.equals("500") == true) {
vars.put("Failure", true)
}
else {
vars.put("Failure", false)
}
When I ran this, I got into infinite loop even my request succeeded. It seems the Failure value was never updated. Any suggestion on this would be appreciated.
This is because you're trying to add a Boolean object into a function which expects a String. In order to be able to store a Boolean value into a JMeter Variable you need to use vars.putObject() function instead like:
vars.putObject("Failure", true)
or surround true with quotation marks so it would look like a String to Groovy:
vars.put("Failure", "true");
Amend your JSR223 Assertion code to look like:
if (ResponseCode.equals("500")) {
vars.put("Failure", "true")
}
else {
vars.put("Failure", "false")
}
Amend your While Controller condition to be just ${Failure}. Using JavaScript is a form of a performance anti-pattern, if you need to perform some scripting - go for Groovy. In particular your case you can just use ${Failure} variable as the condition given it can be either true or false
I finally got it working. In my JSR233 assertion, I updated it to:
if (prev.getResponseCode().equals("500")) {
vars.put("Failure", "true")
}
else {
vars.put("Failure", "false")
}
And it works now.

google.picker.DocsUploadView().setParent('XXXX') issue

Trying to get some help with this code block.
My script first looks for a specific folder and if it exists the pass the id of the folder to the google.picker.DocsUploadView(). When I hard-code the value of setParent to 'gdfid', everything works well. On the other hand, I need the code to be parameterized.
thanks in advance for any assistance
Pete
here's my code:
var gdfid;
function createPicker() {
if (pickerApiLoaded && oauthToken) {
gapi.client.drive.files.list({
"corpora": "user",
"spaces": "drive",
"fields": "files(id,name)",
"q": "name = 'myUploads"
}).then(function(response) {
console.log( response.result.files.length );
if (response.result.files.length > 0) {
console.log( response.result );
gdfid = response.result.files[0].id;
}
//alert('Folder ID: ' + gdfid);
});
var picker = new google.picker.PickerBuilder().
setTitle('Upload to myPratt Folder').
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
enableFeature(google.picker.Feature.NAV_HIDDEN).
addView(new google.picker.DocsUploadView().
setIncludeFolders(false).
setParent('gdfid')). //tried with and without quotes
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
It's probably the .then{} promise code block. I've had lots of trouble with them. The problem is that the .then{} code block has a closed scope.
When you assign gdfid = response.result.files[0].id; it's assumed that it is changing the global variable. But it isn't. It's only creating a local version of gdfid.
I ran around in circles myself for ages trying to figure out how to save external state information from within a .then{} block. Any possible solutions I came up with, were invariably no better than the callback hell that promises were supposed to solve in the first place. I even had problems returning objects out from it. I think the problem is that a .then{} block needs to run from a returned promise. Promises are actually functions earmarked to run in the future. They are subject to scoping restrictions, because they cannot make assumptions about the state of code outside the function. And they only pass object/variables a certain way. Trying to assign globals or returning data the regular way, from inside the .then{} block, is fraught with problems. It will often leave you tearing your hair out.
Try refactoring your code into a function with async/await, and use a try-catch statement to capture promise fails (Note: The try-catch statement still suffers from the global variable isolation problem, but at least it seems to be solely within the catch block. This is only an issue when an error occurs). I find async await much cleaner and easier to understand, and the scoping of variables works more intuitively.
In your case you could rewrite the code thus:
function async createPicker() {
var gdfid;
if (pickerApiLoaded && oauthToken) {
try {
var response = await gapi.client.drive.files.list({
"corpora": "user",
"spaces": "drive",
"fields": "files(id,name)",
"q": "name = 'myUploads"
});
console.log( response.result.files.length );
if (response.result.files.length > 0) {
console.log( response.result );
gdfid = response.result.files[0].id;
}
//alert('Folder ID: ' + gdfid);
var picker = new google.picker.PickerBuilder()
.setTitle('Upload to myPratt Folder')
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.addView(new google.picker.DocsUploadView()
.setIncludeFolders(false)
.setParent(gdfid)) //tried with and without quotes
.setOAuthToken(oauthToken)
.setDeveloperKey(developerKey)
.setCallback(pickerCallback)
.build();
picker.setVisible(true);
} catch (e) {
console.log("Error displaying file list");
}
};
}
The only real difference here, is the await in front of the gapi.client.drive.files
function forces the code to wait for a callback to assign the response variable. This is not too much of a slowdown issue when running single popup UI elements that the user interacts with.
The gdfid variable is no longer global. In fact you don't even need it. You could setParent directly from the response variable.

Inside a try block should only be the instructions that could throw the exception or can put some code not relevant for the exception?

If i know that only one function (take in the example) will throw the exception, what could be the correct way, of the following options?
All in the try block:
try
{
while (someCondition)
{
take();
anotherFunction();
}
}
catch(Exceotion e)
{
//some instructions
}
Inside the block only the function that throw the exception:
while (someCondition)
{
try
{
take();
}
catch....
{
//some instructions
}
anotherFunction();
}
I would use the first way because it's clearer, but there is an explicit rule about this?
Thanks!
The two ways do very different things and depending on what you need the code to do, either can be correct.
In the first example, anotherFunction is not called if there was an exception.
In the second example, the exception is being dealt with in the catch block, and anotherFunction will be executed afterwards.
Along the same lines, in the first example, an exception aborts the whole while loop, whereas in the second example it aborts only a single iteration and continues the loop with the next iteration.

Resources