While condition fails a test step

Hello,
I can’t find solution for the following check. Please give me some tips.

  • There are 5 similar menu options. Start button can be present in every menu option.
  • I need to found what of these menu options has ‘Start’ button
  • perform next steps on this menu option (any one)

Random index is ok, but to check on by one will be better

while Start button is NotPresent
click next menu (x+1)

I tried this code but it fails on while step when the Start button is found

import java.util.concurrent.ThreadLocalRandom as ThreadLocalRandom

def index

def x = ThreadLocalRandom.current().nextInt(1, 5)

while (WebUI.verifyElementNotPresent(findTestObject('Smoke Test Objects/StartButton'), 1, FailureHandling.CONTINUE_ON_FAILURE)) {
    WebUI.click(findTestObject('Smoke Test Objects/x_menu', [('index') : x]))
}

WebUI.click(findTestObject('Smoke Test Objects/StartButton''))

error:

2022-12-09 19:36:40.531 ERROR c.k.k.core.keyword.internal.KeywordMain  - ❌ Web element with id: Smoke Test Objects/StartButton' located by 'By.xpath: xxxxx' is present after '1' second(s) (Root cause: com.kms.katalon.core.exception.StepFailedException: Web element with id: Smoke Test Objects/StartButton' located by 'By.xpath: xxxxx' is present after '1' second(s)

Thanks!

I think your error message just means your “StartButton” is present, so your while loop is not entered. Perhaps, you can use:

WebUI.verifyElementNotVisible()

@grylion54 Thank you for your answer!

Yes, while condition fails when the StartButton is found. It is expected result. But I need this step be passed.

How can I break the while loop?
is it possible to adapt break command to be easily used with Katalon keywords?
e.g.
if (WebUI.verifyElementNotPresent ()=false) break;

@grylion54
I tried it another way.
I have the same problem.

  1. If the next index inside a loop should be verified, test fails. So the step will pass only if loop pass with index x=1

  2. I need to use index (value) in the next steps. How can I get the index value the loop is exit?

def index

for (int x=1; x<6; x++) {
	WebUI.click(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x]))  
   	if (WebUI.verifyElementPresent(findTestObject('Smoke Test Objects/Machine/Visualization/Last screenshot'), 1, FailureHandling.CONTINUE_ON_FAILURE)) break
	   println(x)
 }

Thank you in advance for your patience. I am not a programmer(

For the above statement, you would have needed to use two equal signs to do a comparison. One "equal sign is an equate statement. Also, you should use the curly brackets to ensure you know what you want to happen.

if (WebUI.verifyElementNotPresent()==false) { break;  }

or

if (!WebUI.verifyElementNotPresent()) { break;  }

or

if (WebUI.verifyElementPresent()) { break;  }

In the second statement there is an exclamation point (i.e. ! ) in front of the statement that makes the statement as you want.

Now with the “index”, you can use either a “break” statement or assign “x” a value above 6, like x= 99. The “break” statement is prefered. You can even put a label above your “for” statement and then use it to ensure you leave the loop, like:

Loop:
for (int x=1; x<6; x++) {
	WebUI.click(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x]))  
   	if (WebUI.verifyElementPresent(findTestObject('Smoke Test Objects/Machine/Visualization/Last screenshot'), 1, FailureHandling.CONTINUE_ON_FAILURE)) {
        break Loop;
    }
	println(x)
 }   

If you need to test what the loop counter is, then you can use it like:

    if (x == 1) {...

Perhaps you can pick up some programming tips on www.w3schools

1 Like

@grylion54 Thank you for your help!

I need to know the value of x when the loop is break. I need to use the value of x for the following steps of a test.
I tried to assign index x to an empty array (JS), to create a keyword for this JS code execution, but it seems to complicated and does not work in me case.

Loop:
for (int x=1; x<6; x++) {
	WebUI.click(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x]))  
   	if (WebUI.verifyElementPresent(findTestObject('Smoke Test Objects/Machine/Visualization/Last screenshot'), 1, FailureHandling.CONTINUE_ON_FAILURE)) {
        break Loop;
    }
	println(x)
 }   

There is another programming concept called “scope”. In this case, the “x” is only defined/usable from the “for” statement where we defined it, (int x=1 ...) until the matching curly bracket. So, if you want to use the value of “x” outside of the loop, then you assign it to another variable that has more scope.

def list = new ArrayList()

Loop:
for (int x=1; x<6; x++) {
	WebUI.click(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x]))  
   	if (WebUI.verifyElementPresent(findTestObject('Smoke Test Objects/Machine/Visualization/Last screenshot'), 1, FailureHandling.CONTINUE_ON_FAILURE)) {
        list.add(x)
        break Loop;
    }
	println(x)
 }   // end of scope for x

// we can now use the value of x in **list** outside of the loop.
1 Like

@grylion54 Thank you for your help!
I try to obtain the length of the list array. length method is not recognized. What I do wrong?

def index
def list = new ArrayList()

Loop:
for (int x=1; x<6; x++) {
	WebUI.click(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x]))
	   if (WebUI.verifyElementPresent(findTestObject('Smoke Test Objects/Machine/Visualization/Last screenshot'), 1, FailureHandling.CONTINUE_ON_FAILURE)) {
		list.add(x)
		break Loop;
	}
	println(x)
 }   // end of scope for x

// we can now use the value of x in **list** outside of the loop.

int x = list.length   //value of x is the index for xpath in the next step

name = WebUI.getText(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x])

list.get(0) will get you the value of the index that was found. But to check that it was found at all use list.size(). Anything greater than 0 means it was found.

@grylion54 @danpoleary
Thank you for your help!
The code works:

  • the page where the button is found
  • a loop is broke
  • next step is performed on the page where the button is found

BUT

every time the button is not found in a cycle, step is failed
How to define the condition:
if the loop is break than test step is passed?

def index
def list = new ArrayList()

Loop:
for (int x=1; x<6; x++) {
	WebUI.click(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x]))
	   if (WebUI.verifyElementPresent(findTestObject('Smoke Test Objects/Machine/Visualization/Last screenshot'), 1, FailureHandling.CONTINUE_ON_FAILURE)) {
		list.add(x)
		break Loop;
	}
	println(x)
 }   // end of scope for x

// we can now use the value of x in **list** outside of the loop.

//get the value of the index that was found.

int x=list.get(0)
println(x)

name = WebUI.getText(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : x]))


:x: Test Cases/*** FAILED.
Reason:
com.kms.katalon.core.exception.StepFailedException: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: ‘Object Repository/Smoke Test Objects/Machine/Visualization/Last screenshot’ located by ‘//hk-module-header//descendant::div [contains(@class, ‘ng-star-inserted’)][3]’ not found (Root cause: com.kms.katalon.core.exception.StepFailedException: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: ‘Object Repository/Smoke Test Objects/Machine/Visualization/Last screenshot’ located by ‘//hk-module-header//descendant::div [contains(@class, ‘ng-star-inserted’)][3]’ not found

CONTINUE_ON_FAILURE will still show an error but continue. If you do not want an error, use OPTIONAL instead. Also, where you assign x=list.get(0), I would change to

if (list.size() > 0) {
     name = WebUI.getText(findTestObject('Smoke Test Objects/Machine/Visualization/NAVI/i visu in a list get text', [('index') : list.get(0)]))
}

You can add an else to handle if it is never found, such as:

else {
    KeywordUtil.markFailed(">>>custom error message failed")
}