Websocket test passed but katalon status display done

I have a script testing websocket messages and even if my test is passed katalon dipslay it as done and when i execute the test suite the status i the report is incomplete.

import org.java_websocket.client.WebSocketClient
import org.java_websocket.handshake.ServerHandshake
import java.net.URI
import groovy.json.JsonSlurper
import internal.GlobalVariable
import groovy.json.JsonOutput

import com.kms.katalon.core.util.KeywordUtil
import com.kms.katalon.core.testdata.TestDataFactory




class MyWebSocketClient extends WebSocketClient {
  MyWebSocketClient(URI serverUri) {
        super(serverUri)  // Ajouter les headers (dont le cookie)
		println ('serverUri : '+ serverUri)
    }

    @Override
    void onOpen(ServerHandshake handshakedata) {
        println ("Connexion ouverte ")
        
        // Envoyer la requête WebSocket après la connexion
        String handShake = '''
        {
            "protocol": "json",
            "version": 1
        }
        '''.stripIndent().trim() + "\u001E" // Ajouter le caractère de fin de message WebSocket (0x1E)
        
        this.send(handShake)
        println "handShake envoyée : $handShake"
		
		String request = '''
        {
            "protocol": "json",
            "version": 1,
            "arguments": [{
                "debug": true
            }],
            "invocationId": "0",
            "target": "ListFunctions",
            "type": 1
        }
        '''.stripIndent().trim() + "\u001E" // Ajouter le caractère de fin de message WebSocket (0x1E)
		
		this.send(request)
		println "Requête listFunctions envoyée : $request"
		Thread.sleep(1000)
    }
	
	

    @Override
    void onMessage(String message) {
        println "Message reçu : " + message

        
        def jsonSlurper = new JsonSlurper()
    def response = jsonSlurper.parseText(message)  

    if (response.type == 1) {
        validateResponse(message)  // Exécuter la validation uniquement pour type = 1
    } else {
        println "Message ignoré (type ${response.type})"
    }

    }

	@Override
		void onClose(int code, String reason, boolean remote) {
		println "Connexion fermée : Code=$code, Raison=${reason ?: 'Aucune raison fournie'}, Fermeture initiée par " + (remote ? "le serveur" : "le client")
}


    @Override
    void onError(Exception ex) {
        println "Erreur : ${ex.message}"
    }
	
void validateResponse(String message) {
    def jsonSlurper = new JsonSlurper()
    def response = jsonSlurper.parseText(message)  // Désérialisation de la réponse JSON

    // Chargement des modèles attendus depuis le Data File
    def testData = TestDataFactory.findTestData('Data Files/ListFunctions')
    def expectedFunctionsMap = [:]
    for (int i = 1; i <= testData.getRowNumbers(); i++) {
        expectedFunctionsMap[testData.getValue('functionName', i)] = [
            functionName: testData.getValue('functionName', i),
            description: testData.getValue('description', i),
			parameters: testData.getValue('parameters', i)
        ]
    }

    def errors = []  // Liste pour stocker les erreurs

    if (response.type == 1) {
        response.arguments[0].functions.each { function ->
            def validationResult = validateFunction(function, expectedFunctionsMap[function.functionName])
            if (validationResult) {
                errors << validationResult
            }
        }

        if (errors.isEmpty()) {
            KeywordUtil.markPassed("All functions are returned correctly")
        } else {
            KeywordUtil.markFailed("Test failed: ${errors.size()} error(s) detected:\n- " + errors.join("\n- "))
        }
    } 
}

// Fonction de validation d'une function
String validateFunction(function, expectedFunction) {
	println ("name : "+ function.functionName)
    if (!expectedFunction) {
        return "Function inattendu : ${function.functionName}"
    }
    if (function.functionName != expectedFunction.functionName) {
        return "functionName incorrect pour ${function.functionName} : attendu '${expectedFunction.functionName}', reçu '${function.functionName}'"
    }
    if (function.description.replace("\n", " ").trim() != expectedFunction.description.trim()) {
        return "description incorrect pour ${function.functionName} : attendu '${expectedFunction.description.trim()}', reçu '${function.description.trim()}'"
    }
	// Désérialisation de expectedModel.parameters s'il est stocké sous forme de String
	def expectedParameters = expectedFunction.parameters instanceof String ?
		new JsonSlurper().parseText(expectedFunction.parameters) : expectedFunction.parameters
	
		// Vérification après transformation en JSON standardisé
	if (JsonOutput.toJson(function.parameters) != JsonOutput.toJson(expectedParameters)) {
		return "parameters incorrect pour ${function.functionName} : attendu '${JsonOutput.toJson(expectedParameters)}', reçu '${JsonOutput.toJson(function.parameters)}'"
	}	
	
    return null  // Pas d'erreur
}
	
}

// URL du serveur WebSocket
def serverUri = new URI(GlobalVariable.ws_URI + 'endpoints/v1/assistant')

// Créer une instance du client WebSocket
def client = new MyWebSocketClient(serverUri)

// Connecter au serveur WebSocket
client.connect()

// Attendre que la connexion soit Ă©tablie
while (!client.isOpen()) {
	println "En attente de l'ouverture de la connexion..."
    Thread.sleep(300)
}

// Attendre un moment pour recevoir des messages
Thread.sleep(5000)

// Fermer la connexion
client.close()
1 Like

What is your problem?
What did you expected to see?
What did you actually see?
How do you want your script and/or Katalon to behave?

When test is passed i want katalon to display passed status instead of done.
in the testsuite iwahnt the status passed instead of incomplete

You wrote that Katalon Studio displayed done when your test passed.

I don’t see what you mean. Please take a screenshot of Katalon Studio display, mark the “done” which you don’t like, and share it here.


You wrote that Katalon Studio showed a test suite is incomplete .

I don’t see what you mean. Please take a screenshot of Katalon Studio display, mark the “incomplete” which you don’t like, and share it here.

Test case execution :

testsuite execution :

Thank you for the screenshots you shared.

But still I don’t understand what you don’t like.

Please edit the screenshot so that you do the following:

As you can see in the console log and in the script in my previous messages , i use KeywordUtil.markPassed("All functions are returned correctly") when my test is ok and in the logs everything is OK and the markPassed is executed.
But the status of the testcase execution in the up right is done instead of passed.

The second point is : when i execute the same testcase in a test suite , it ended with the status incomplete.

Thank you for your description

Now I understand your problem.


I tried to reproduce your case on my machine, but I couldn’t see <Done> at all.

As I could not reproduce the problem, I have no idea. I would quit this topic.

What I see from your image is that your Jobs never completed. Note on the right side of the “Job Progress” area, you have zero of 1 and zero of 2 completed and NOT 1 of 1 and 2 of 2. Something is causing your test case to not complete and that is what you should be concerned about.
The “Done” is what I get when the test blows up and doesn’t go through to the end of the test, overwise, it should state “Completed”.