How do I get a test case to report successful when it cannot find a test object?

I want to look for a test object and if it cannot find it, report test case successful, instead of failing. Also acceptable to change for loop end index to something that can detect the correct number of loops.

Test Case

import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import static com.kms.katalon.core.testobject.ObjectRepository.findWindowsObject
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
import com.kms.katalon.core.cucumber.keyword.CucumberBuiltinKeywords as CucumberKW
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.testcase.TestCase as TestCase
import com.kms.katalon.core.testdata.TestData as TestData
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.windows.keyword.WindowsBuiltinKeywords as Windows
import internal.GlobalVariable as GlobalVariable
import org.openqa.selenium.Keys as Keys

WebUI.openBrowser('https://dg.coupons.com/signin/?done=%2Fcoupons%2F', FailureHandling.STOP_ON_FAILURE)

WebUI.setText(findTestObject('Page_Sign In/input_EMAIL OR PHONE_username'), Username, FailureHandling.STOP_ON_FAILURE)

WebUI.setText(findTestObject('Page_Sign In/input_Password_password'), Password, FailureHandling.STOP_ON_FAILURE)

WebUI.click(findTestObject('Object Repository/Page_Sign In/input_Sign in_btn-sign-in'), FailureHandling.STOP_ON_FAILURE)

for (def index : (1..40)) {
    WebUI.scrollToPosition(0, 99999, FailureHandling.STOP_ON_FAILURE)

    WebUI.delay(0.5, FailureHandling.STOP_ON_FAILURE)
}

WebUI.scrollToPosition(0, 0, FailureHandling.STOP_ON_FAILURE)

WebUI.delay(0.5, FailureHandling.STOP_ON_FAILURE)

WebUI.click(findTestObject('Page_Coupons Gallery/span_Add', [('Slot') : 1]), FailureHandling.STOP_ON_FAILURE)

WebUI.delay(1, FailureHandling.STOP_ON_FAILURE)

WebUI.click(findTestObject('Page_Coupons Gallery/label_Ok I understand Close window'), FailureHandling.STOP_ON_FAILURE)

for (def index : (1..99999)) {
    WebUI.click(findTestObject('Page_Coupons Gallery/span_Add', [('Slot') : (index * 2) + 1]), FailureHandling.STOP_ON_FAILURE)
}

Test Object:

xpath=(.//*[normalize-space(text()) and normalize-space(.)='✓'])[${Slot}]/following::span[1]

Console Log:

2019-11-13 19:36:30.825 DEBUG testcase.Main                            - 1: click(findTestObject("Page_Coupons Gallery/span_Add", ["Slot":index * 2 + 1]))
2019-11-13 19:36:32.331 ERROR c.k.k.c.w.keyword.builtin.ClickKeyword   - ❌ javascript error: Cannot read property 'left' of undefined

I think I have the logic worked out

if ((WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Sign In/input_Sign in_btn-sign-in'),2))) {	
		
			WebUI.click(findTestObject('Page_Coupons Gallery/span_Add', [('Slot') : (index * 2) + 1]))
			
		} else {
		
			WS.comment("Insert Test Case Successful Here")
			
		}

now I just need to figure out what the method is for exiting a test case and report successful

Have you take a look at Verify Element Not Present keyword ?

I have. I can’t seem to get the if statement to work. It always returns true even when it shouldn’t.
Additionally, I still don’t know what to do after that. How do I get the script to end immediately when true and report a successful test case?

See #2 above

Edit: I just realized why it was always returning true. I’ll get that fixed in a moment. I still need to know about getting the script to end immediately when true and report a successful test case.

Hi @BetaLeaf

Try to use return; where WS.comment("Insert Test Case Successful Here") is currently is.

Ok that works. Still trying to figure out the if statement thing tho. I still need to try a few things and will post back once if I still need help

1 Like

Ok I think I still need help.

This is the script I am trying to run. Basically, if test object not found, closed browser & return success.

if (WebUI.verifyElementNotPresent(findTestObject('Page_Coupons Gallery/span_Add'), 2) == true) {
    WebUI.closeBrowser()
    return null
}

but it always returns true.

I realized a moment ago that the test object is

xpath=(.//*[normalize-space(text()) and normalize-space(.)='✓'])[${Slot}]/following::span[1]

which ${Slot} needed a default value of 1. This should be working, but it isn’t. It doesn’t find something that is there. It should be returning false in the current case. Project files below.

It would help if I could see the variables update during debugging, but no variables ever show up and I can’t find a way to watch them

Project files

Dollar General Coupon Bot.7z (1.2 MB)

@BetaLeaf

In this section:

if (WebUI.verifyElementNotPresent(findTestObject('Page_Coupons Gallery/span_Add'), 2) == true) {
    WebUI.closeBrowser()
    return null
}

Are you expecting that the Slot variable within the test object would be defaulted to 1 ? You’re not passing the variable Slot from your test case into it. I suspect, if you change verifyElementNotPresent to verifyElementPresent, you would find that the test case fails because the locator of span_Add would be

xpath=(.//*[normalize-space(text()) and normalize-space(.)='✓'])[${Slot}]/following::span[1]

which since it’s not a valid locator (containing ${ }) the element cannot be found.

The variable should be defined with a default value, unless I am doing something wrong. See picture below.

I see that, but are you confusing Test Case variable with Test Object variable ?

Unless you pass the Slot variable intofindTestObject('id', ['slot': slot]) The Slot variable within the test object will not be aware of the existence of the Slot test case variable.

I tried what you suggested, still doesn’t work. Is there a way to view the current value of a variable during execution/debugging?

Just place a break point there and switch to Debug view (there’s an icon on near the top-right corner).

@BetaLeaf You can Try and Catch the error like this:
try {
//put you finding object code here
}
catch (StepFailedException e){

}
catch (StepErrorException e){

}

Because the errors are catches so testcase report will be successfull

@BetaLeaf Answering your many questions tidily would take me too long to construct the post so I’m just going to dump some stuff here. Try these suggestions and cherry-pick what you need.

Avoid debugger: just println your vars:

image
  https://docs.katalon.com/katalon-studio/docs/test-case-variables.html#manage-test-case-variables

I think part of your problem is not waiting until the webpage is ready. I see you use a wait time of 2 seconds but that might not begin or end at appropriate times. A better strategy would be to wait for all objects that should be there to be proven to be there before you look for things that should not be there. Make sense? I think that’s why you’re seeing some of your not-present attempts always return true. You can do that with a single method right there in your test case. Let me know what you think.

Any time you want to break out of a loop just do that:

for(...) {

  //stuff

  if(some_condition) {
    break
  }
}

If the test has issues it will report them. If it doesn’t it will pass. You don’t need code to say that specifically. All you need is to get the logic and flow correct.

If you have more questions, shout.