From 6d9aa2602dde742111f9bf6e51df6e211f0d9191 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Fri, 9 Dec 2022 19:38:46 +0000 Subject: [PATCH 01/13] tests: add integration tests for credential schemas --- .../kotlin/api_models/CredentialSchema.kt | 11 ++ .../src/test/kotlin/common/TestConstants.kt | 18 ++ .../CredentialSchemasSteps.kt | 180 ++++++++++++++++++ .../src/test/kotlin/runners/E2eTestsRunner.kt | 2 +- .../credential_schemas.feature | 39 ++++ 5 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt create mode 100644 tests/e2e-tests/src/test/kotlin/common/TestConstants.kt create mode 100644 tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt create mode 100644 tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature diff --git a/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt b/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt new file mode 100644 index 0000000000..bf0f5d66b5 --- /dev/null +++ b/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt @@ -0,0 +1,11 @@ +package api_models + +data class CredentialSchema( + var id: String? = null, + var name: String? = null, + var version: String? = null, + var description: String? = null, + var author: String? = null, + var attributes: List? = listOf(""), + var tags: List? = listOf("") +) \ No newline at end of file diff --git a/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt new file mode 100644 index 0000000000..f4d6d3593e --- /dev/null +++ b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt @@ -0,0 +1,18 @@ +package common + +import api_models.CredentialSchema +import java.util.* + +object TestConstants { + + val CREDENTIAL_SCHEMA = CredentialSchema( + author = "University", + name = "Student schema", + description = "Simple student credentials schema", + attributes = listOf("name", "age"), + tags = listOf("school", "students"), + version = "1.0" + ) + + val RANDOM_UUID = UUID.randomUUID().toString() +} \ No newline at end of file diff --git a/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt b/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt new file mode 100644 index 0000000000..03e76e1684 --- /dev/null +++ b/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt @@ -0,0 +1,180 @@ +package features.credential_schemas + +import common.Agents.Acme +import common.TestConstants +import common.Utils.lastResponse +import io.cucumber.java.en.Then +import io.cucumber.java.en.When +import net.serenitybdd.screenplay.rest.interactions.Get +import net.serenitybdd.screenplay.rest.interactions.Post +import net.serenitybdd.screenplay.rest.questions.ResponseConsequence +import org.apache.http.HttpStatus.* +import org.hamcrest.CoreMatchers.* +import org.hamcrest.Matchers.containsString +import org.hamcrest.Matchers.emptyString +import java.util.* + +class CredentialSchemasSteps { + + @When("Acme creates a new credential schema") + fun acmeCreatesANewCredentialSchema() { + Acme.attemptsTo( + Post.to("/schema-registry/schemas") + .with { + it.header("Content-Type", "application/json") + it.body(TestConstants.CREDENTIAL_SCHEMA) + } + ) + } + + @Then("New credential schema is available") + fun newCredentialSchemaIsAvailable() { + Acme.should( + ResponseConsequence.seeThatResponse("New schema created") { + it.statusCode(SC_CREATED) + it.body("id", not(emptyString())) + it.body("authored", not(emptyString())) + it.body("kind", containsString("VerifiableCredentialSchema")) + it.body("name", containsString(TestConstants.CREDENTIAL_SCHEMA.name)) + it.body("description", containsString(TestConstants.CREDENTIAL_SCHEMA.description)) + it.body("version", containsString(TestConstants.CREDENTIAL_SCHEMA.version)) + TestConstants.CREDENTIAL_SCHEMA.tags!!.forEach { tag -> + it.body("tags", hasItem(tag)) + } + TestConstants.CREDENTIAL_SCHEMA.attributes!!.forEach { attr -> + it.body("attributes", hasItem(attr)) + } + } + ) + } + + @When("Acme creates {int} schemas") + fun acmeCreatesMultipleSchemas(numberOfSchemes: Int) { + for (i in 0 until numberOfSchemes) { + Acme.attemptsTo( + Post.to("/schema-registry/schemas") + .with { + it.header("Content-Type", "application/json") + it.body(TestConstants.CREDENTIAL_SCHEMA) + } + ) + Acme.should( + ResponseConsequence.seeThatResponse("New schema created") { + it.statusCode(SC_CREATED) + } + ) + } + } + + @Then("All {int} schemas can be accessed with pagination {int}") + fun theyCanBeAccessedWithPagination(numberOfSchemes: Int, pagination: Int) { + for (i in 0 until numberOfSchemes / 2) { + val resource = lastResponse().get("next") ?: "/schema-registry/schemas?limit=$pagination" + Acme.attemptsTo( + Get.resource(resource) + ) + Acme.should( + ResponseConsequence.seeThatResponse("Schemas achieved") { + it.statusCode(SC_OK) + } + ) + } + } + + @When("Acme tries to get schemas with negative limit") + fun acmeTriesToGetSchemasWithNegativeLimit() { + Acme.attemptsTo( + Get.resource("/schema-registry/schemas?offset=999") + ) + Acme.should( + ResponseConsequence.seeThatResponse("Schemas get failure") { + it.statusCode(SC_OK) + } + ) + } + + @When("Acme creates a new schema with empty id") + fun acmeCreatesANewSchemaWithEmptyId() { + val wrongSchema = TestConstants.CREDENTIAL_SCHEMA + wrongSchema.id = "" + Acme.attemptsTo( + Post.to("/schema-registry/schemas") + .with { + it.header("Content-Type", "application/json") + it.body(wrongSchema) + } + ) + } + + @Then("New schema creation is failed with empty id error") + fun newSchemaCreationIsFailedWithEmptyIdError() { + Acme.should( + ResponseConsequence.seeThatResponse("Get schema invalid id failure") { + it.statusCode(SC_BAD_REQUEST) + it.body("msg", containsString("Invalid UUID: at 'id'")) + } + ) + } + + @When("Acme creates a new schema with zero attributes") + fun acmeCreatesANewSchemaWithZeroAttributes() { + val wrongSchema = TestConstants.CREDENTIAL_SCHEMA + wrongSchema.attributes = null + Acme.attemptsTo( + Post.to("/schema-registry/schemas") + .with { + it.header("Content-Type", "application/json") + it.body(wrongSchema) + } + ) + } + + @Then("New schema creation is failed with zero attributes error") + fun newSchemaCreationIsFailedWithZeroAttributesError() { + Acme.should( + ResponseConsequence.seeThatResponse("Get schema invalid attributes failure") { + it.statusCode(SC_BAD_REQUEST) + } + ) + } + + @When("Acme creates a new schema with fixed id") + fun acmeCreatesANewSchemaWithFixedId() { + val wrongSchema = TestConstants.CREDENTIAL_SCHEMA + wrongSchema.id = TestConstants.RANDOM_UUID + Acme.attemptsTo( + Post.to("/schema-registry/schemas") + .with { + it.header("Content-Type", "application/json") + it.body(wrongSchema) + } + ) + Acme.should( + ResponseConsequence.seeThatResponse("New schema created") { + it.statusCode(SC_CREATED) + } + ) + } + + @When("Acme tries to create a new schema with same id") + fun acmeTriesToCreateANewSchemaWithSameId() { + val wrongSchema = TestConstants.CREDENTIAL_SCHEMA + wrongSchema.id = TestConstants.RANDOM_UUID + Acme.attemptsTo( + Post.to("/schema-registry/schemas") + .with { + it.header("Content-Type", "application/json") + it.body(wrongSchema) + } + ) + } + + @Then("Id duplicate error is thrown") + fun idDuplicateErrorIsThrown() { + Acme.should( + ResponseConsequence.seeThatResponse("New schema creation error: same UUID") { + it.statusCode(SC_BAD_REQUEST) + } + ) + } +} diff --git a/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt b/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt index 0c9844cce7..acff31fb4f 100644 --- a/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt +++ b/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt @@ -6,7 +6,7 @@ import org.junit.runner.RunWith @CucumberOptions( features = [ - "src/test/resources/features" + "src/test/resources/features/credential_schemas" ], glue = ["features", "extentions"], snippets = CucumberOptions.SnippetType.CAMELCASE, diff --git a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature new file mode 100644 index 0000000000..446311f46e --- /dev/null +++ b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature @@ -0,0 +1,39 @@ +Feature: Credential schemas + + Scenario: Successful schema creation + When Acme creates a new credential schema + Then New credential schema is available + + Scenario: Multiple schema creation + When Acme creates 6 schemas + Then All 6 schemas can be accessed with pagination 2 + + Scenario: Schema creation failure with empty id + When Acme creates a new schema with empty id + Then New schema creation is failed with empty id error + +# # Not working for now (can be successfully created) +# Scenario: Schema creation with 2 same IDs fails +# When Acme creates a new schema with fixed id +# And Acme tries to create a new schema with same id +# Then Id duplicate error is thrown + +# # Not working for now (can be created with "" list) +# Scenario: Schema creation failure with zero attributes +# When Acme creates a new schema with zero attributes +# Then New schema creation is failed with zero attributes error + +# # Not working for now (returns empty result with success) +# Scenario: Get schemas with negative limit +# When Acme tries to get schemas with negative limit +# Then Negative limit error is thrown in response + +# # Not working for now (returns empty result with success) +# Scenario: Get schemas with negative offset +# When Acme tries to get schemas with negative offset +# Then Wrong offset error is thrown in response +# +# # Not working for now (returns empty result with success) +# Scenario: Get schemas with offset greater than amount of schemas +# When Acme tries to get schemas with offset greater than amount of schemas +# Then Wrong offset error is thrown in response From 8d9d08297cff50bc4536de5fe2174cf08adbe123 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Fri, 9 Dec 2022 19:45:50 +0000 Subject: [PATCH 02/13] test: test --- tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt | 2 +- tests/e2e-tests/src/test/kotlin/common/TestConstants.kt | 2 +- tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt b/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt index bf0f5d66b5..1bdf8480d2 100644 --- a/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt +++ b/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt @@ -8,4 +8,4 @@ data class CredentialSchema( var author: String? = null, var attributes: List? = listOf(""), var tags: List? = listOf("") -) \ No newline at end of file +) diff --git a/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt index f4d6d3593e..92a8cc1c05 100644 --- a/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt +++ b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt @@ -15,4 +15,4 @@ object TestConstants { ) val RANDOM_UUID = UUID.randomUUID().toString() -} \ No newline at end of file +} diff --git a/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt b/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt index acff31fb4f..0c9844cce7 100644 --- a/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt +++ b/tests/e2e-tests/src/test/kotlin/runners/E2eTestsRunner.kt @@ -6,7 +6,7 @@ import org.junit.runner.RunWith @CucumberOptions( features = [ - "src/test/resources/features/credential_schemas" + "src/test/resources/features" ], glue = ["features", "extentions"], snippets = CucumberOptions.SnippetType.CAMELCASE, From ab483f8ddca54ef51d36018459c3681aaa7a41f9 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Mon, 12 Dec 2022 20:01:55 +0000 Subject: [PATCH 03/13] test: test --- infrastructure/local/.env | 2 +- .../kotlin/api_models/CredentialSchema.kt | 3 + .../src/test/kotlin/common/TestConstants.kt | 12 +- .../features/connection/ConnectionSteps.kt | 109 +++++------ .../CredentialSchemasSteps.kt | 174 ++++++++---------- .../kotlin/features/did/ResolveDidSteps.kt | 31 ---- .../IssueCredentialsSteps.kt | 71 ++++--- .../features/connection/connection.feature | 2 +- .../credential_schemas.feature | 58 +++--- .../features/did/resolve_did.feature | 6 - .../issue_credentials.feature | 2 +- 11 files changed, 210 insertions(+), 260 deletions(-) delete mode 100644 tests/e2e-tests/src/test/kotlin/features/did/ResolveDidSteps.kt delete mode 100644 tests/e2e-tests/src/test/resources/features/did/resolve_did.feature diff --git a/infrastructure/local/.env b/infrastructure/local/.env index da837321ed..62b1cc2c6b 100644 --- a/infrastructure/local/.env +++ b/infrastructure/local/.env @@ -1,4 +1,4 @@ MERCURY_MEDIATOR_VERSION=0.2.0 IRIS_SERVICE_VERSION=0.1.0 -PRISM_AGENT_VERSION=0.16.1 +PRISM_AGENT_VERSION=0.17.0 PORT=80 diff --git a/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt b/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt index 1bdf8480d2..2674057727 100644 --- a/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt +++ b/tests/e2e-tests/src/main/kotlin/api_models/CredentialSchema.kt @@ -6,6 +6,9 @@ data class CredentialSchema( var version: String? = null, var description: String? = null, var author: String? = null, + var authored: String? = null, + var kind: String? = null, + var self: String? = null, var attributes: List? = listOf(""), var tags: List? = listOf("") ) diff --git a/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt index 92a8cc1c05..114298239a 100644 --- a/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt +++ b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt @@ -1,11 +1,15 @@ package common import api_models.CredentialSchema -import java.util.* +import java.util.UUID object TestConstants { + val CREDENTIAL_SCHEMAS = CredentialSchemas + val RANDOM_CONSTAND_UUID = UUID.randomUUID().toString() +} - val CREDENTIAL_SCHEMA = CredentialSchema( +object CredentialSchemas { + val STUDENT_SCHEMA = CredentialSchema( author = "University", name = "Student schema", description = "Simple student credentials schema", @@ -13,6 +17,4 @@ object TestConstants { tags = listOf("school", "students"), version = "1.0" ) - - val RANDOM_UUID = UUID.randomUUID().toString() -} +} \ No newline at end of file diff --git a/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt b/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt index 0e18dbc86d..fcaca95be8 100644 --- a/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt +++ b/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt @@ -8,6 +8,7 @@ import common.Utils.lastResponseObject import common.Utils.wait import io.cucumber.java.en.Then import io.cucumber.java.en.When +import net.serenitybdd.screenplay.Actor import net.serenitybdd.screenplay.rest.interactions.Get import net.serenitybdd.screenplay.rest.interactions.Post import net.serenitybdd.screenplay.rest.questions.ResponseConsequence @@ -16,19 +17,19 @@ import org.hamcrest.CoreMatchers.* class ConnectionSteps { - @When("Acme generates a connection invitation") - fun inviterGeneratesAConnectionInvitation() { + @When("{actor} generates a connection invitation") + fun inviterGeneratesAConnectionInvitation(inviter: Actor) { // Acme(Issuer) initiates a connection // and sends it to Bob(Holder) out-of-band, e.g. using QR-code - val connectionLabel = "Connection with ${Bob.name}" - Acme.attemptsTo( + val connectionLabel = "New Connection" + inviter.attemptsTo( Post.to("/connections") .with { it.header("Content-Type", "application/json") it.body("""{"label": "$connectionLabel"}""") } ) - Acme.should( + inviter.should( ResponseConsequence.seeThatResponse("Generates connection request") { response -> response.statusCode(201) response.body("connectionId", notNullValue()) @@ -39,45 +40,45 @@ class ConnectionSteps { } ) // Acme remembers invitation URL to send it out of band to Bob - Acme.remember( + inviter.remember( "invitationUrl", lastResponseObject("", Connection::class) .invitation.invitationUrl.split("=")[1] ) - Acme.remember( + inviter.remember( "invitation", lastResponseObject("invitation", Invitation::class) ) // Acme remembers its connection ID for further use - Acme.remember( + inviter.remember( "connectionId", lastResponseObject("", Connection::class) .connectionId ) } - @When("Bob receives the connection invitation") - fun inviteeReceivesTheConnectionInvitation() { + @When("{actor} receives the connection invitation from {actor}") + fun inviteeReceivesTheConnectionInvitation(invitee: Actor, inviter: Actor) { // Here out of band transfer of connection QR code is happening // and Bob (Holder) gets an invitation URL // they're accepting connection invitation by POST request specifying achieved invitation // we demonstrate it by Bob remembering invitationUrl that Acme recalls - Bob.remember("invitationUrl", Acme.recall("invitationUrl")) + invitee.remember("invitationUrl", inviter.recall("invitationUrl")) } - @When("Bob sends a connection request to Acme") - fun inviteeSendsAConnectionRequestToInviter() { + @When("{actor} sends a connection request to {actor}") + fun inviteeSendsAConnectionRequestToInviter(invitee: Actor, inviter: Actor) { // Bob accepts connection using achieved out-of-band invitation - Bob.attemptsTo( + invitee.attemptsTo( Post.to("/connection-invitations") .with { it.header("Content-Type", "application/json") - it.body("""{"invitation": "${Bob.recall("invitationUrl")}"}""") + it.body("""{"invitation": "${invitee.recall("invitationUrl")}"}""") } ) - val acmeInvitation = Acme.recall("invitation") - Bob.should( + val acmeInvitation = inviter.recall("invitation") + invitee.should( ResponseConsequence.seeThatResponse("Accepts connection request") { response -> response.statusCode(200) response.body("connectionId", notNullValue()) @@ -91,18 +92,18 @@ class ConnectionSteps { response.body("state", containsString("ConnectionRequestPending")) } ) - Bob.remember("connectionId", lastResponseObject("", Connection::class).connectionId) + invitee.remember("connectionId", lastResponseObject("", Connection::class).connectionId) } - @When("Acme receives the connection request") - fun inviterReceivesTheConnectionRequest() { + @When("{actor} receives the connection request") + fun inviterReceivesTheConnectionRequest(inviter: Actor) { wait( { - Acme.attemptsTo( - Get.resource("/connections/${Acme.recall("connectionId")}"), + inviter.attemptsTo( + Get.resource("/connections/${inviter.recall("connectionId")}"), ) - Acme.should( - ResponseConsequence.seeThatResponse("Get connection ${Acme.recall("connectionId")}") { + inviter.should( + ResponseConsequence.seeThatResponse("Get connection ${inviter.recall("connectionId")}") { it.statusCode(200) } ) @@ -112,17 +113,17 @@ class ConnectionSteps { ) } - @When("Acme sends a connection response to Bob") - fun inviterSendsAConnectionResponseToInvitee() { + @When("{actor} sends a connection response to {actor}") + fun inviterSendsAConnectionResponseToInvitee(inviter: Actor, invitee: Actor) { // Acme(Issuer) checks their connections to check if invitation was accepted by Bob(Holder) // and sends final connection response wait( { - Acme.attemptsTo( - Get.resource("/connections/${Acme.recall("connectionId")}"), + inviter.attemptsTo( + Get.resource("/connections/${inviter.recall("connectionId")}"), ) - Acme.should( - ResponseConsequence.seeThatResponse("Get connection ${Acme.recall("connectionId")}") { + inviter.should( + ResponseConsequence.seeThatResponse("Get connection ${inviter.recall("connectionId")}") { it.statusCode(200) } ) @@ -132,16 +133,16 @@ class ConnectionSteps { ) } - @When("Bob receives the connection response") - fun inviteeReceivesTheConnectionResponse() { + @When("{actor} receives the connection response") + fun inviteeReceivesTheConnectionResponse(invitee: Actor) { // Bob (Holder) receives final connection response wait( { - Bob.attemptsTo( - Get.resource("/connections/${Bob.recall("connectionId")}") + invitee.attemptsTo( + Get.resource("/connections/${invitee.recall("connectionId")}") ) - Bob.should( - ResponseConsequence.seeThatResponse("Get connection ${Bob.recall("connectionId")}") { + invitee.should( + ResponseConsequence.seeThatResponse("Get connection ${invitee.recall("connectionId")}") { it.statusCode(200) } ) @@ -151,36 +152,36 @@ class ConnectionSteps { ) } - @Then("Acme and Bob have a connection") - fun inviterAndInviteeHaveAConnection() { + @Then("{actor} and {actor} have a connection") + fun inviterAndInviteeHaveAConnection(inviter: Actor, invitee: Actor) { // Connection established. Both parties exchanged their DIDs with each other - Acme.attemptsTo( - Get.resource("/connections/${Acme.recall("connectionId")}"), + inviter.attemptsTo( + Get.resource("/connections/${inviter.recall("connectionId")}"), ) - Acme.should( - ResponseConsequence.seeThatResponse("Get connection ${Acme.recall("connectionId")}") { + inviter.should( + ResponseConsequence.seeThatResponse("Get connection ${inviter.recall("connectionId")}") { it.statusCode(200) } ) - Acme.remember("connection", lastResponseObject("", Connection::class)) + inviter.remember("connection", lastResponseObject("", Connection::class)) - Bob.attemptsTo( - Get.resource("/connections/${Bob.recall("connectionId")}") + invitee.attemptsTo( + Get.resource("/connections/${invitee.recall("connectionId")}") ) - Bob.should( - ResponseConsequence.seeThatResponse("Get connection ${Bob.recall("connectionId")}") { + invitee.should( + ResponseConsequence.seeThatResponse("Get connection ${invitee.recall("connectionId")}") { it.statusCode(200) } ) - Bob.remember("connection", lastResponseObject("", Connection::class)) + invitee.remember("connection", lastResponseObject("", Connection::class)) - assertThat(Acme.recall("connection").myDid) - .isEqualTo(Bob.recall("connection").theirDid) - assertThat(Acme.recall("connection").theirDid) - .isEqualTo(Bob.recall("connection").myDid) - assertThat(Acme.recall("connection").state) + assertThat(inviter.recall("connection").myDid) + .isEqualTo(invitee.recall("connection").theirDid) + assertThat(inviter.recall("connection").theirDid) + .isEqualTo(invitee.recall("connection").myDid) + assertThat(inviter.recall("connection").state) .isEqualTo("ConnectionResponseSent") - assertThat(Bob.recall("connection").state) + assertThat(invitee.recall("connection").state) .isEqualTo("ConnectionResponseReceived") } } diff --git a/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt b/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt index 03e76e1684..c938b9b9d5 100644 --- a/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt +++ b/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt @@ -1,10 +1,13 @@ package features.credential_schemas -import common.Agents.Acme +import api_models.CredentialSchema import common.TestConstants -import common.Utils.lastResponse +import common.Utils.lastResponseObject +import common.Utils.toJsonPath +import io.cucumber.java.PendingException import io.cucumber.java.en.Then import io.cucumber.java.en.When +import net.serenitybdd.screenplay.Actor import net.serenitybdd.screenplay.rest.interactions.Get import net.serenitybdd.screenplay.rest.interactions.Post import net.serenitybdd.screenplay.rest.questions.ResponseConsequence @@ -16,111 +19,96 @@ import java.util.* class CredentialSchemasSteps { - @When("Acme creates a new credential schema") - fun acmeCreatesANewCredentialSchema() { - Acme.attemptsTo( + @When("{actor} creates a new credential schema") + fun acmeCreatesANewCredentialSchema(actor: Actor) { + actor.attemptsTo( Post.to("/schema-registry/schemas") .with { it.header("Content-Type", "application/json") - it.body(TestConstants.CREDENTIAL_SCHEMA) + it.body(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA) } ) } - @Then("New credential schema is available") - fun newCredentialSchemaIsAvailable() { - Acme.should( + @Then("{actor} sees new credential schema is available") + fun newCredentialSchemaIsAvailable(actor: Actor) { + actor.should( ResponseConsequence.seeThatResponse("New schema created") { it.statusCode(SC_CREATED) it.body("id", not(emptyString())) it.body("authored", not(emptyString())) it.body("kind", containsString("VerifiableCredentialSchema")) - it.body("name", containsString(TestConstants.CREDENTIAL_SCHEMA.name)) - it.body("description", containsString(TestConstants.CREDENTIAL_SCHEMA.description)) - it.body("version", containsString(TestConstants.CREDENTIAL_SCHEMA.version)) - TestConstants.CREDENTIAL_SCHEMA.tags!!.forEach { tag -> + it.body("name", containsString(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA.name)) + it.body("description", containsString(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA.description)) + it.body("version", containsString(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA.version)) + TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA.tags!!.forEach { tag -> it.body("tags", hasItem(tag)) } - TestConstants.CREDENTIAL_SCHEMA.attributes!!.forEach { attr -> + TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA.attributes!!.forEach { attr -> it.body("attributes", hasItem(attr)) } } ) } - @When("Acme creates {int} schemas") - fun acmeCreatesMultipleSchemas(numberOfSchemes: Int) { - for (i in 0 until numberOfSchemes) { - Acme.attemptsTo( + @When("{actor} creates {int} new schemas") + fun acmeCreatesMultipleSchemas(actor: Actor, numberOfSchemas: Int) { + val createdSchemas: MutableList = mutableListOf() + repeat(numberOfSchemas) { + actor.attemptsTo( Post.to("/schema-registry/schemas") .with { it.header("Content-Type", "application/json") - it.body(TestConstants.CREDENTIAL_SCHEMA) + it.body(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA) } ) - Acme.should( + actor.should( ResponseConsequence.seeThatResponse("New schema created") { it.statusCode(SC_CREATED) } ) + createdSchemas.add(lastResponseObject("", CredentialSchema::class)) } + actor.remember("createdSchemas", createdSchemas) } - @Then("All {int} schemas can be accessed with pagination {int}") - fun theyCanBeAccessedWithPagination(numberOfSchemes: Int, pagination: Int) { - for (i in 0 until numberOfSchemes / 2) { - val resource = lastResponse().get("next") ?: "/schema-registry/schemas?limit=$pagination" - Acme.attemptsTo( - Get.resource(resource) + @Then("{actor} can access all of them one by one") + fun theyCanBeAccessedWithPagination(actor: Actor) { + actor.recall>("createdSchemas").forEach { schema -> + actor.attemptsTo( + Get.resource("/schema-registry/schemas/${schema.id}") ) - Acme.should( - ResponseConsequence.seeThatResponse("Schemas achieved") { + actor.should( + ResponseConsequence.seeThatResponse("Schema achieved") { it.statusCode(SC_OK) } ) } } - @When("Acme tries to get schemas with negative limit") - fun acmeTriesToGetSchemasWithNegativeLimit() { - Acme.attemptsTo( - Get.resource("/schema-registry/schemas?offset=999") - ) - Acme.should( - ResponseConsequence.seeThatResponse("Schemas get failure") { - it.statusCode(SC_OK) - } - ) - } - - @When("Acme creates a new schema with empty id") - fun acmeCreatesANewSchemaWithEmptyId() { - val wrongSchema = TestConstants.CREDENTIAL_SCHEMA - wrongSchema.id = "" - Acme.attemptsTo( + @When("{actor} creates a new schema with some id") + fun acmeCreatesANewSchemaWithFixedId(actor: Actor) { + val wrongSchema = TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA + wrongSchema.id = TestConstants.RANDOM_CONSTAND_UUID + actor.attemptsTo( Post.to("/schema-registry/schemas") .with { it.header("Content-Type", "application/json") it.body(wrongSchema) } ) - } - - @Then("New schema creation is failed with empty id error") - fun newSchemaCreationIsFailedWithEmptyIdError() { - Acme.should( - ResponseConsequence.seeThatResponse("Get schema invalid id failure") { - it.statusCode(SC_BAD_REQUEST) - it.body("msg", containsString("Invalid UUID: at 'id'")) + actor.should( + ResponseConsequence.seeThatResponse("New schema created") { + it.statusCode(SC_CREATED) } ) } - @When("Acme creates a new schema with zero attributes") - fun acmeCreatesANewSchemaWithZeroAttributes() { - val wrongSchema = TestConstants.CREDENTIAL_SCHEMA - wrongSchema.attributes = null - Acme.attemptsTo( + @When("{actor} tries to create a new schema with identical id") + fun acmeTriesToCreateANewSchemaWithSameId(actor: Actor) { + val wrongSchema = TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA + wrongSchema.id = TestConstants.RANDOM_CONSTAND_UUID + actor.attemptsTo( Post.to("/schema-registry/schemas") .with { it.header("Content-Type", "application/json") @@ -129,52 +117,50 @@ class CredentialSchemasSteps { ) } - @Then("New schema creation is failed with zero attributes error") - fun newSchemaCreationIsFailedWithZeroAttributesError() { - Acme.should( - ResponseConsequence.seeThatResponse("Get schema invalid attributes failure") { - it.statusCode(SC_BAD_REQUEST) - } - ) + @Then("{actor} sees the request failure with identical id error") + fun idDuplicateErrorIsThrown(actor: Actor) { + try { + actor.should( + ResponseConsequence.seeThatResponse("New schema creation error: same UUID") { + it.statusCode(SC_BAD_REQUEST) + } + ) + } catch(err: AssertionError) { + println(err.message) + throw PendingException("BUG: New credential schema CAN be created with same UUID.") + } } - @When("Acme creates a new schema with fixed id") - fun acmeCreatesANewSchemaWithFixedId() { - val wrongSchema = TestConstants.CREDENTIAL_SCHEMA - wrongSchema.id = TestConstants.RANDOM_UUID - Acme.attemptsTo( + @When("{actor} tries to create a new schema with {word} in field {word}") + fun acmeTriesToCreateANewSchemaWithField(actor: Actor, value: String, field: String) { + actor.attemptsTo( Post.to("/schema-registry/schemas") .with { - it.header("Content-Type", "application/json") - it.body(wrongSchema) + it.body( + toJsonPath(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA).set(field, value).jsonString() + ) } ) - Acme.should( - ResponseConsequence.seeThatResponse("New schema created") { - it.statusCode(SC_CREATED) - } - ) } - @When("Acme tries to create a new schema with same id") - fun acmeTriesToCreateANewSchemaWithSameId() { - val wrongSchema = TestConstants.CREDENTIAL_SCHEMA - wrongSchema.id = TestConstants.RANDOM_UUID - Acme.attemptsTo( - Post.to("/schema-registry/schemas") - .with { - it.header("Content-Type", "application/json") - it.body(wrongSchema) - } + @When("{actor} tries to get schemas with {int} in parameter {word}") + fun acmeTriesToCreateANewSchemaWithParameter(actor: Actor, value: Int, parameter: String) { + actor.attemptsTo( + Get.resource("/schema-registry/schemas?$parameter=$value") ) } - @Then("Id duplicate error is thrown") - fun idDuplicateErrorIsThrown() { - Acme.should( - ResponseConsequence.seeThatResponse("New schema creation error: same UUID") { - it.statusCode(SC_BAD_REQUEST) - } - ) + @Then("{actor} sees the request with status {int}") + fun heSeesTheRequestFailureWithErrorStatus(actor: Actor, errorStatusCode: Int) { + try { + actor.should( + ResponseConsequence.seeThatResponse { + it.statusCode(errorStatusCode) + } + ) + } catch(err: AssertionError) { + println(err.message) + throw PendingException("BUG: credential schemas CAN be accessed with negative limit and offset.") + } } } diff --git a/tests/e2e-tests/src/test/kotlin/features/did/ResolveDidSteps.kt b/tests/e2e-tests/src/test/kotlin/features/did/ResolveDidSteps.kt deleted file mode 100644 index 49f3008fed..0000000000 --- a/tests/e2e-tests/src/test/kotlin/features/did/ResolveDidSteps.kt +++ /dev/null @@ -1,31 +0,0 @@ -package features.did - -import common.Agents.Acme -import io.cucumber.java.en.Then -import io.cucumber.java.en.When -import net.serenitybdd.screenplay.rest.interactions.Get -import net.serenitybdd.screenplay.rest.questions.ResponseConsequence - -class ResolveDidSteps { - @When("I resolve existing DID by DID reference") - fun iResolveExistingDIDByDIDReference() { - Acme.attemptsTo( - Get.resource("/connections") - ) - } - - @Then("Response code is 200") - fun responseCodeIs() { - Acme.should( - ResponseConsequence.seeThatResponse("DID has required fields") { - it.statusCode(200) - } - ) - } - - @Then("I achieve standard compatible DID document") - fun iAchieveStandardCompatibleDIDDocument() { - // to be filled later when did endpoint works - } - -} diff --git a/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt b/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt index a355ace419..5579ef3cb9 100644 --- a/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt +++ b/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt @@ -8,32 +8,31 @@ import net.serenitybdd.screenplay.rest.interactions.Post import net.serenitybdd.screenplay.rest.questions.ResponseConsequence import api_models.Connection import api_models.Credential -import common.Agents.Acme -import common.Agents.Bob import common.Utils.lastResponseList import common.Utils.lastResponseObject import common.Utils.wait import features.connection.ConnectionSteps +import net.serenitybdd.screenplay.Actor class IssueCredentialsSteps { - @Given("Acme and Bob have an existing connection") - fun acmeAndBobHaveAnExistingConnection() { + @Given("{actor} and {actor} have an existing connection") + fun acmeAndBobHaveAnExistingConnection(issuer: Actor, holder: Actor) { val connectionSteps = ConnectionSteps() - connectionSteps.inviterGeneratesAConnectionInvitation() - connectionSteps.inviteeReceivesTheConnectionInvitation() - connectionSteps.inviteeSendsAConnectionRequestToInviter() - connectionSteps.inviterReceivesTheConnectionRequest() - connectionSteps.inviterSendsAConnectionResponseToInvitee() - connectionSteps.inviteeReceivesTheConnectionResponse() - connectionSteps.inviterAndInviteeHaveAConnection() + connectionSteps.inviterGeneratesAConnectionInvitation(issuer) + connectionSteps.inviteeReceivesTheConnectionInvitation(holder, issuer) + connectionSteps.inviteeSendsAConnectionRequestToInviter(holder, issuer) + connectionSteps.inviterReceivesTheConnectionRequest(issuer) + connectionSteps.inviterSendsAConnectionResponseToInvitee(issuer, holder) + connectionSteps.inviteeReceivesTheConnectionResponse(holder) + connectionSteps.inviterAndInviteeHaveAConnection(issuer, holder) } - @Given("Acme offers a credential") - fun acmeOffersACredential() { + @Given("{actor} offers a credential") + fun acmeOffersACredential(issuer: Actor) { val newCredential = Credential( schemaId = "schema:1234", - subjectId = Acme.recall("connection").theirDid, + subjectId = issuer.recall("connection").theirDid, validityPeriod = 3600, automaticIssuance = false, awaitConfirmation = false, @@ -43,14 +42,14 @@ class IssueCredentialsSteps { ) ) - Acme.attemptsTo( + issuer.attemptsTo( Post.to("/issue-credentials/credential-offers") .with { it.header("Content-Type", "application/json") it.body(newCredential) } ) - Acme.should( + issuer.should( ResponseConsequence.seeThatResponse("The issue credential offer created") { it.statusCode(201) } @@ -59,14 +58,14 @@ class IssueCredentialsSteps { // TODO: add check that newCredential object corresponds to the output of restapi call here } - @When("Bob requests the credential") - fun bobRequestsTheCredential() { + @When("{actor} requests the credential") + fun bobRequestsTheCredential(holder: Actor) { wait( { - Bob.attemptsTo( + holder.attemptsTo( Get.resource("/issue-credentials/records") ) - Bob.should( + holder.should( ResponseConsequence.seeThatResponse("Credential records") { it.statusCode(200) } @@ -78,26 +77,26 @@ class IssueCredentialsSteps { val recordId = lastResponseList("items", Credential::class) .findLast { it.protocolState == "OfferReceived" }!!.recordId - Bob.remember("recordId", recordId) + holder.remember("recordId", recordId) - Bob.attemptsTo( + holder.attemptsTo( Post.to("/issue-credentials/records/${recordId}/accept-offer") ) - Bob.should( + holder.should( ResponseConsequence.seeThatResponse("Accept offer") { it.statusCode(200) } ) } - @When("Acme issues the credential") - fun acmeIssuesTheCredential() { + @When("{actor} issues the credential") + fun acmeIssuesTheCredential(issuer: Actor) { wait( { - Acme.attemptsTo( + issuer.attemptsTo( Get.resource("/issue-credentials/records") ) - Acme.should( + issuer.should( ResponseConsequence.seeThatResponse("Credential records") { it.statusCode(200) } @@ -109,10 +108,10 @@ class IssueCredentialsSteps { ) val recordId = lastResponseList("items", Credential::class) .findLast { it.protocolState == "RequestReceived" }!!.recordId - Acme.attemptsTo( + issuer.attemptsTo( Post.to("/issue-credentials/records/${recordId}/issue-credential") ) - Acme.should( + issuer.should( ResponseConsequence.seeThatResponse("Issue credential") { it.statusCode(200) } @@ -120,10 +119,10 @@ class IssueCredentialsSteps { wait( { - Acme.attemptsTo( + issuer.attemptsTo( Get.resource("/issue-credentials/records/${recordId}") ) - Acme.should( + issuer.should( ResponseConsequence.seeThatResponse("Credential records") { it.statusCode(200) } @@ -134,14 +133,14 @@ class IssueCredentialsSteps { ) } - @Then("Bob has the credential issued") - fun bobHasTheCredentialIssued() { + @Then("{actor} has the credential issued") + fun bobHasTheCredentialIssued(holder: Actor) { wait( { - Bob.attemptsTo( - Get.resource("/issue-credentials/records/${Bob.recall("recordId")}") + holder.attemptsTo( + Get.resource("/issue-credentials/records/${holder.recall("recordId")}") ) - Bob.should( + holder.should( ResponseConsequence.seeThatResponse("Credential records") { it.statusCode(200) } diff --git a/tests/e2e-tests/src/test/resources/features/connection/connection.feature b/tests/e2e-tests/src/test/resources/features/connection/connection.feature index 8bac8293bb..fba1f4763d 100644 --- a/tests/e2e-tests/src/test/resources/features/connection/connection.feature +++ b/tests/e2e-tests/src/test/resources/features/connection/connection.feature @@ -3,7 +3,7 @@ Feature: RFC 0160 Agent connection functions Scenario: Establish a connection between two agents When Acme generates a connection invitation - And Bob receives the connection invitation + And Bob receives the connection invitation from Acme And Bob sends a connection request to Acme And Acme receives the connection request And Acme sends a connection response to Bob diff --git a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature index 446311f46e..f26cad7957 100644 --- a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature +++ b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature @@ -2,38 +2,34 @@ Feature: Credential schemas Scenario: Successful schema creation When Acme creates a new credential schema - Then New credential schema is available + Then He sees new credential schema is available - Scenario: Multiple schema creation - When Acme creates 6 schemas - Then All 6 schemas can be accessed with pagination 2 + Scenario Outline: Multiple schema creation + When Acme creates new schemas + Then He can access all of them one by one + Examples: + | schemas | + | 4 | - Scenario: Schema creation failure with empty id - When Acme creates a new schema with empty id - Then New schema creation is failed with empty id error + Scenario: Schema creation with identical id should fail + When Acme creates a new schema with some id + And Acme tries to create a new schema with identical id + Then He sees the request failure with identical id error -# # Not working for now (can be successfully created) -# Scenario: Schema creation with 2 same IDs fails -# When Acme creates a new schema with fixed id -# And Acme tries to create a new schema with same id -# Then Id duplicate error is thrown + Scenario Outline: Wrong specified fields for schema generation requests should fail + When Acme tries to create a new schema with in field + Then He sees the request with status + Examples: + | field | value | status | + | id | -1 | 400 | + | attributes | null | 400 | -# # Not working for now (can be created with "" list) -# Scenario: Schema creation failure with zero attributes -# When Acme creates a new schema with zero attributes -# Then New schema creation is failed with zero attributes error - -# # Not working for now (returns empty result with success) -# Scenario: Get schemas with negative limit -# When Acme tries to get schemas with negative limit -# Then Negative limit error is thrown in response - -# # Not working for now (returns empty result with success) -# Scenario: Get schemas with negative offset -# When Acme tries to get schemas with negative offset -# Then Wrong offset error is thrown in response -# -# # Not working for now (returns empty result with success) -# Scenario: Get schemas with offset greater than amount of schemas -# When Acme tries to get schemas with offset greater than amount of schemas -# Then Wrong offset error is thrown in response + Scenario Outline: Wrong specified filter parameters for schema generation requests should fail + When Acme tries to get schemas with in parameter + Then He sees the request with status + Examples: + | parameter | value | status | + | limit | 1 | 200 | + | limit | -1 | 400 | + | offset | -1 | 400 | + | offset | 1000000 | 400 | diff --git a/tests/e2e-tests/src/test/resources/features/did/resolve_did.feature b/tests/e2e-tests/src/test/resources/features/did/resolve_did.feature deleted file mode 100644 index 287aafed9e..0000000000 --- a/tests/e2e-tests/src/test/resources/features/did/resolve_did.feature +++ /dev/null @@ -1,6 +0,0 @@ -Feature: Resolve DID - - Scenario: Successful DID resolve - When I resolve existing DID by DID reference - Then Response code is 200 - And I achieve standard compatible DID document diff --git a/tests/e2e-tests/src/test/resources/features/issue_credentials/issue_credentials.feature b/tests/e2e-tests/src/test/resources/features/issue_credentials/issue_credentials.feature index 6f8de6d2b8..155a3192f0 100644 --- a/tests/e2e-tests/src/test/resources/features/issue_credentials/issue_credentials.feature +++ b/tests/e2e-tests/src/test/resources/features/issue_credentials/issue_credentials.feature @@ -2,7 +2,7 @@ Feature: RFC0453 Issue Credentials Protocol Scenario: Issue a credential with the Issuer beginning with an offer - And Acme and Bob have an existing connection + Given Acme and Bob have an existing connection When Acme offers a credential And Bob requests the credential And Acme issues the credential From 7361b117e37e459f9019d0546f87107d95af204f Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 12:36:54 +0000 Subject: [PATCH 04/13] test: test --- .github/workflows/e2e-tests.yml | 59 ++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 563bc2c248..c203b60634 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -25,6 +25,8 @@ jobs: run-e2e-tests: name: "Run e2e tests" runs-on: ubuntu-latest + env: + REPORTS_DIR: "tests/e2e-tests/target/site/serenity" steps: - name: Checkout uses: actions/checkout@v3 @@ -72,25 +74,74 @@ jobs: up-flags: "--wait" down-flags: "--volumes" + - name: Start services for verifier + env: + PORT: 8070 + uses: isbang/compose-action@v1.4.1 + with: + compose-file: "./infrastructure/shared/docker-compose.yml" + compose-flags: "--env-file ./infrastructure/local/.env -p verifier" + up-flags: "--wait" + down-flags: "--volumes" + - name: Run e2e tests env: ATALA_GITHUB_TOKEN: ${{ secrets.ATALA_GITHUB_TOKEN }} run: | - ../../infrastructure/local/update_env.sh - cat ../../infrastructure/local/.env ./gradlew test --tests "E2eTestsRunner" - uses: actions/upload-artifact@v2 if: always() with: name: e2e-tests-result - path: tests/e2e-tests/target/site/serenity + path: ${{ env.REPORTS_DIR }} - name: Publish e2e test Results if: always() id: publish-unit-tests uses: EnricoMi/publish-unit-test-result-action@v2 with: - junit_files: "tests/e2e-tests/target/site/serenity/SERENITY-JUNIT-*.xml" + junit_files: "${{ env.REPORTS_DIR }}/SERENITY-JUNIT-*.xml" comment_title: "E2E Test Results" check_name: "E2E Test Results" + + - name: Extract test results + id: analyze_test_results + # if: github.ref_name == 'master' + run: | + TOTAL_FAILURES=0 + TOTAL_TESTS=0 + for XML_RESULTS in $(find ${{ env.REPORTS_DIR }} -type f -name 'SERENITY-JUNIT-*.xml'); do + TESTS=$(xmllint --xpath 'string(//@tests)' ${XML_RESULTS}) + FAILURES=$(xmllint --xpath 'string(//@failures)' ${XML_RESULTS}) + ERRORS=$(xmllint --xpath 'string(//@errors)' ${XML_RESULTS}) + TOTAL_FAILURES=$((TOTAL_FAILURES + FAILURES + ERRORS)) + TOTAL_TESTS=$((TOTAL_TESTS + TESTS)) + done + if [[ ${TOTAL_FAILURES} > 0 || ${TOTAL_TESTS} == 0 ]] ; then + CONCLUSION=failure + else + CONCLUSION=success + fi + echo "conclusion=${CONCLUSION}" >> $GITHUB_OUTPUT + echo "tests=${TOTAL_TESTS}" >> $GITHUB_OUTPUT + echo "failures=${TOTAL_FAILURES}" >> $GITHUB_OUTPUT + + - name: Slack Notification + # if: github.ref_name == 'master' + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: atala-qa-results + SLACK_COLOR: ${{ steps.analyze_test_results.outputs.conclusion }} + SLACK_MESSAGE: "Total: ${{ steps.analyze_test_results.outputs.tests }}\nFailures: ${{ steps.analyze_test_results.outputs.failures }}" + SLACK_TITLE: "Atala PRISM V2 E2E tests: ${{ steps.analyze_test_results.outputs.conclusion }}" + SLACK_USERNAME: circleci + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + + - name: notify-tests + uses: ivanklee86/xunit-slack-reporter@v1.4.0 + env: + EXIT_CODE_FROM_REPORT: "True" + SLACK_CHANNEL: atala-qa-results + SLACK_TOKEN: ${{ secrets.SLACK_WEBHOOK }} + XUNIT_PATH: "${{ env.REPORTS_DIR }}/SERENITY-JUNIT-*.xml" From 05cd1149efcf9d508605a98bf9f0a041eb3d62a5 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 13:28:41 +0000 Subject: [PATCH 05/13] test: test --- .github/workflows/e2e-tests.yml | 46 ++++++++++--------- tests/e2e-tests/build.gradle.kts | 9 +++- .../credential_schemas.feature | 1 + 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index c203b60634..23c9215a39 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -36,6 +36,9 @@ jobs: with: java-version: openjdk@1.11 + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + - name: Install Python uses: actions/setup-python@v2 with: @@ -109,23 +112,32 @@ jobs: id: analyze_test_results # if: github.ref_name == 'master' run: | - TOTAL_FAILURES=0 - TOTAL_TESTS=0 - for XML_RESULTS in $(find ${{ env.REPORTS_DIR }} -type f -name 'SERENITY-JUNIT-*.xml'); do - TESTS=$(xmllint --xpath 'string(//@tests)' ${XML_RESULTS}) - FAILURES=$(xmllint --xpath 'string(//@failures)' ${XML_RESULTS}) - ERRORS=$(xmllint --xpath 'string(//@errors)' ${XML_RESULTS}) - TOTAL_FAILURES=$((TOTAL_FAILURES + FAILURES + ERRORS)) - TOTAL_TESTS=$((TOTAL_TESTS + TESTS)) - done - if [[ ${TOTAL_FAILURES} > 0 || ${TOTAL_TESTS} == 0 ]] ; then - CONCLUSION=failure + JSON_RESULTS="${{ env.REPORTS_DIR }}/serenity-summary.json" + if [ -f "${JSON_RESULTS}" ]; then + TOTAL_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.total')" + SUCCESS_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.success')" + PENDING_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.pending')" + SKIPPED_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.skipped')" + IGNORED_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.ignored')" + FAILED_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.failure')" + TESTS_WITH_ERRORS="$(cat ${JSON_RESULTS} | jq '.results.counts.error')" + if [[ ${FAILED_TESTS} > 0 || ${TESTS_WITH_ERRORS} > 0 ]] ; then + CONCLUSION=failure + else + CONCLUSION=success + fi else - CONCLUSION=success + CONCLUSION=failure + TOTAL_TESTS=0 + FAILED_TESTS=0 fi echo "conclusion=${CONCLUSION}" >> $GITHUB_OUTPUT echo "tests=${TOTAL_TESTS}" >> $GITHUB_OUTPUT - echo "failures=${TOTAL_FAILURES}" >> $GITHUB_OUTPUT + echo "failures=${FAILED_TESTS}" >> $GITHUB_OUTPUT + echo "errors=${TESTS_WITH_ERRORS}" >> $GITHUB_OUTPUT + echo "pending=${PENDING_TESTS}" >> $GITHUB_OUTPUT + echo "skipped=${SKIPPED_TESTS}" >> $GITHUB_OUTPUT + echo "ignored=${IGNORED_TESTS}" >> $GITHUB_OUTPUT - name: Slack Notification # if: github.ref_name == 'master' @@ -137,11 +149,3 @@ jobs: SLACK_TITLE: "Atala PRISM V2 E2E tests: ${{ steps.analyze_test_results.outputs.conclusion }}" SLACK_USERNAME: circleci SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - - - name: notify-tests - uses: ivanklee86/xunit-slack-reporter@v1.4.0 - env: - EXIT_CODE_FROM_REPORT: "True" - SLACK_CHANNEL: atala-qa-results - SLACK_TOKEN: ${{ secrets.SLACK_WEBHOOK }} - XUNIT_PATH: "${{ env.REPORTS_DIR }}/SERENITY-JUNIT-*.xml" diff --git a/tests/e2e-tests/build.gradle.kts b/tests/e2e-tests/build.gradle.kts index f62fb5b3eb..f523d0a103 100644 --- a/tests/e2e-tests/build.gradle.kts +++ b/tests/e2e-tests/build.gradle.kts @@ -18,8 +18,6 @@ dependencies { testImplementation("junit:junit:4.13.2") implementation("net.serenity-bdd:serenity-core:3.4.3") implementation("net.serenity-bdd:serenity-cucumber:3.4.3") - implementation("net.serenity-bdd:serenity-single-page-report:3.4.3") - implementation("net.serenity-bdd:serenity-json-summary-report:3.4.3") implementation("net.serenity-bdd:serenity-screenplay-rest:3.4.3") // Beautify exceptions handling assertions testImplementation("org.assertj:assertj-core:3.23.1") @@ -27,6 +25,13 @@ dependencies { testImplementation("com.jayway.jsonpath:json-path:2.7.0") } +buildscript { + dependencies { + classpath("net.serenity-bdd:serenity-single-page-report:3.4.3") + classpath("net.serenity-bdd:serenity-json-summary-report:3.4.3") + } +} + /** * Add HTML one-pager and JSON summary report to be produced */ diff --git a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature index f26cad7957..46894b66ac 100644 --- a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature +++ b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature @@ -4,6 +4,7 @@ Feature: Credential schemas When Acme creates a new credential schema Then He sees new credential schema is available + @skip Scenario Outline: Multiple schema creation When Acme creates new schemas Then He can access all of them one by one From c1b764109c0a90925f7c06c50bbf059c6d130efa Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 13:52:47 +0000 Subject: [PATCH 06/13] test: test --- .github/workflows/e2e-tests.yml | 10 +++++++--- .../credential_schemas/credential_schemas.feature | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 23c9215a39..59828e83e1 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -88,13 +88,13 @@ jobs: down-flags: "--volumes" - name: Run e2e tests + continue-on-error: true env: ATALA_GITHUB_TOKEN: ${{ secrets.ATALA_GITHUB_TOKEN }} run: | - ./gradlew test --tests "E2eTestsRunner" + ./gradlew test reports --tests "E2eTestsRunner" - uses: actions/upload-artifact@v2 - if: always() with: name: e2e-tests-result path: ${{ env.REPORTS_DIR }} @@ -145,7 +145,11 @@ jobs: env: SLACK_CHANNEL: atala-qa-results SLACK_COLOR: ${{ steps.analyze_test_results.outputs.conclusion }} - SLACK_MESSAGE: "Total: ${{ steps.analyze_test_results.outputs.tests }}\nFailures: ${{ steps.analyze_test_results.outputs.failures }}" + SLACK_MESSAGE: | + Total: ${{ steps.analyze_test_results.outputs.tests }} + Failed: ${{ steps.analyze_test_results.outputs.failures }} + Errors in tests: ${{ steps.analyze_test_results.outputs.errors }} + Skipped (known bugs): ${{ steps.analyze_test_results.outputs.skipped }} SLACK_TITLE: "Atala PRISM V2 E2E tests: ${{ steps.analyze_test_results.outputs.conclusion }}" SLACK_USERNAME: circleci SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature index 46894b66ac..27e0c72297 100644 --- a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature +++ b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature @@ -4,7 +4,6 @@ Feature: Credential schemas When Acme creates a new credential schema Then He sees new credential schema is available - @skip Scenario Outline: Multiple schema creation When Acme creates new schemas Then He can access all of them one by one @@ -12,6 +11,7 @@ Feature: Credential schemas | schemas | | 4 | + @skip Scenario: Schema creation with identical id should fail When Acme creates a new schema with some id And Acme tries to create a new schema with identical id From 04c4f5390ad05b3466ec180aecbd15a780c827e6 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 14:05:07 +0000 Subject: [PATCH 07/13] test: test --- .github/workflows/e2e-tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 59828e83e1..5de38a9284 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -92,7 +92,8 @@ jobs: env: ATALA_GITHUB_TOKEN: ${{ secrets.ATALA_GITHUB_TOKEN }} run: | - ./gradlew test reports --tests "E2eTestsRunner" + ./gradlew test --tests "E2eTestsRunner" + ./gradlew reports - uses: actions/upload-artifact@v2 with: From 9c836daaef61b8cbe0815833c4a5a6a2c391bc90 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 14:14:53 +0000 Subject: [PATCH 08/13] test: test --- .github/workflows/e2e-tests.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 5de38a9284..eebaa1a3b8 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -114,6 +114,11 @@ jobs: # if: github.ref_name == 'master' run: | JSON_RESULTS="${{ env.REPORTS_DIR }}/serenity-summary.json" + CONCLUSION=failure + TOTAL_TESTS=0 + FAILED_TESTS=0 + SKIPPED_TESTS=0 + TESTS_WITH_ERRORS=0 if [ -f "${JSON_RESULTS}" ]; then TOTAL_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.total')" SUCCESS_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.success')" @@ -122,15 +127,9 @@ jobs: IGNORED_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.ignored')" FAILED_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.failure')" TESTS_WITH_ERRORS="$(cat ${JSON_RESULTS} | jq '.results.counts.error')" - if [[ ${FAILED_TESTS} > 0 || ${TESTS_WITH_ERRORS} > 0 ]] ; then - CONCLUSION=failure - else + if [[ ${FAILED_TESTS} == 0 || ${TESTS_WITH_ERRORS} == 0 ]] ; then CONCLUSION=success fi - else - CONCLUSION=failure - TOTAL_TESTS=0 - FAILED_TESTS=0 fi echo "conclusion=${CONCLUSION}" >> $GITHUB_OUTPUT echo "tests=${TOTAL_TESTS}" >> $GITHUB_OUTPUT From dd4d31b869e9f1e125617e0583df377082e593a3 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 14:35:09 +0000 Subject: [PATCH 09/13] test: test --- .github/workflows/e2e-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index eebaa1a3b8..c7510b7f1f 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -92,7 +92,7 @@ jobs: env: ATALA_GITHUB_TOKEN: ${{ secrets.ATALA_GITHUB_TOKEN }} run: | - ./gradlew test --tests "E2eTestsRunner" + ./gradlew test --tests "E2eTestsRunner" || true ./gradlew reports - uses: actions/upload-artifact@v2 From 65871dbaf149b26d92679229150384e16237c1c0 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 14:56:48 +0000 Subject: [PATCH 10/13] test: test --- .github/workflows/e2e-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index c7510b7f1f..c698f88f8f 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -113,7 +113,7 @@ jobs: id: analyze_test_results # if: github.ref_name == 'master' run: | - JSON_RESULTS="${{ env.REPORTS_DIR }}/serenity-summary.json" + JSON_RESULTS="target/site/serenity/serenity-summary.json" CONCLUSION=failure TOTAL_TESTS=0 FAILED_TESTS=0 From 53dc33dcdd95502923467578850364cdedc514c4 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 15:12:57 +0000 Subject: [PATCH 11/13] test: test --- .github/workflows/e2e-tests.yml | 2 +- .../credential_schemas/credential_schemas.feature | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index c698f88f8f..265c77c568 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -127,7 +127,7 @@ jobs: IGNORED_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.ignored')" FAILED_TESTS="$(cat ${JSON_RESULTS} | jq '.results.counts.failure')" TESTS_WITH_ERRORS="$(cat ${JSON_RESULTS} | jq '.results.counts.error')" - if [[ ${FAILED_TESTS} == 0 || ${TESTS_WITH_ERRORS} == 0 ]] ; then + if [[ ${FAILED_TESTS} == 0 && ${TESTS_WITH_ERRORS} == 0 ]] ; then CONCLUSION=success fi fi diff --git a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature index 27e0c72297..264adb29e7 100644 --- a/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature +++ b/tests/e2e-tests/src/test/resources/features/credential_schemas/credential_schemas.feature @@ -11,12 +11,6 @@ Feature: Credential schemas | schemas | | 4 | - @skip - Scenario: Schema creation with identical id should fail - When Acme creates a new schema with some id - And Acme tries to create a new schema with identical id - Then He sees the request failure with identical id error - Scenario Outline: Wrong specified fields for schema generation requests should fail When Acme tries to create a new schema with in field Then He sees the request with status @@ -25,12 +19,18 @@ Feature: Credential schemas | id | -1 | 400 | | attributes | null | 400 | + @skip @bug + Scenario: Schema creation with identical id should fail + When Acme creates a new schema with some id + And Acme tries to create a new schema with identical id + Then He sees the request failure with identical id error + + @skip @bug Scenario Outline: Wrong specified filter parameters for schema generation requests should fail When Acme tries to get schemas with in parameter Then He sees the request with status Examples: | parameter | value | status | - | limit | 1 | 200 | | limit | -1 | 400 | | offset | -1 | 400 | | offset | 1000000 | 400 | From 79901cdb238705bb6c0e408899f43a463a44bd18 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 15:58:07 +0000 Subject: [PATCH 12/13] test: test --- .../src/test/kotlin/common/CredentialSchemas.kt | 14 ++++++++++++++ .../src/test/kotlin/common/TestConstants.kt | 12 ------------ .../kotlin/features/connection/ConnectionSteps.kt | 2 -- .../credential_schemas/CredentialSchemasSteps.kt | 4 ---- .../issue_credentials/IssueCredentialsSteps.kt | 1 - 5 files changed, 14 insertions(+), 19 deletions(-) create mode 100644 tests/e2e-tests/src/test/kotlin/common/CredentialSchemas.kt diff --git a/tests/e2e-tests/src/test/kotlin/common/CredentialSchemas.kt b/tests/e2e-tests/src/test/kotlin/common/CredentialSchemas.kt new file mode 100644 index 0000000000..b08d1b776f --- /dev/null +++ b/tests/e2e-tests/src/test/kotlin/common/CredentialSchemas.kt @@ -0,0 +1,14 @@ +package common + +import api_models.CredentialSchema + +object CredentialSchemas { + val STUDENT_SCHEMA = CredentialSchema( + author = "University", + name = "Student schema", + description = "Simple student credentials schema", + attributes = listOf("name", "age"), + tags = listOf("school", "students"), + version = "1.0" + ) +} diff --git a/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt index 114298239a..6d5514d67f 100644 --- a/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt +++ b/tests/e2e-tests/src/test/kotlin/common/TestConstants.kt @@ -1,20 +1,8 @@ package common -import api_models.CredentialSchema import java.util.UUID object TestConstants { val CREDENTIAL_SCHEMAS = CredentialSchemas val RANDOM_CONSTAND_UUID = UUID.randomUUID().toString() } - -object CredentialSchemas { - val STUDENT_SCHEMA = CredentialSchema( - author = "University", - name = "Student schema", - description = "Simple student credentials schema", - attributes = listOf("name", "age"), - tags = listOf("school", "students"), - version = "1.0" - ) -} \ No newline at end of file diff --git a/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt b/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt index fcaca95be8..5120fe1099 100644 --- a/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt +++ b/tests/e2e-tests/src/test/kotlin/features/connection/ConnectionSteps.kt @@ -25,7 +25,6 @@ class ConnectionSteps { inviter.attemptsTo( Post.to("/connections") .with { - it.header("Content-Type", "application/json") it.body("""{"label": "$connectionLabel"}""") } ) @@ -73,7 +72,6 @@ class ConnectionSteps { invitee.attemptsTo( Post.to("/connection-invitations") .with { - it.header("Content-Type", "application/json") it.body("""{"invitation": "${invitee.recall("invitationUrl")}"}""") } ) diff --git a/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt b/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt index c938b9b9d5..eff543a7a4 100644 --- a/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt +++ b/tests/e2e-tests/src/test/kotlin/features/credential_schemas/CredentialSchemasSteps.kt @@ -24,7 +24,6 @@ class CredentialSchemasSteps { actor.attemptsTo( Post.to("/schema-registry/schemas") .with { - it.header("Content-Type", "application/json") it.body(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA) } ) @@ -58,7 +57,6 @@ class CredentialSchemasSteps { actor.attemptsTo( Post.to("/schema-registry/schemas") .with { - it.header("Content-Type", "application/json") it.body(TestConstants.CREDENTIAL_SCHEMAS.STUDENT_SCHEMA) } ) @@ -93,7 +91,6 @@ class CredentialSchemasSteps { actor.attemptsTo( Post.to("/schema-registry/schemas") .with { - it.header("Content-Type", "application/json") it.body(wrongSchema) } ) @@ -111,7 +108,6 @@ class CredentialSchemasSteps { actor.attemptsTo( Post.to("/schema-registry/schemas") .with { - it.header("Content-Type", "application/json") it.body(wrongSchema) } ) diff --git a/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt b/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt index 5579ef3cb9..c508aa7cf9 100644 --- a/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt +++ b/tests/e2e-tests/src/test/kotlin/features/issue_credentials/IssueCredentialsSteps.kt @@ -45,7 +45,6 @@ class IssueCredentialsSteps { issuer.attemptsTo( Post.to("/issue-credentials/credential-offers") .with { - it.header("Content-Type", "application/json") it.body(newCredential) } ) From 413ac60339d5028d217f9c66bef9c61f36a35ff8 Mon Sep 17 00:00:00 2001 From: Anton Baliasnikov Date: Tue, 13 Dec 2022 16:02:02 +0000 Subject: [PATCH 13/13] test: test --- .github/workflows/e2e-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 265c77c568..944948a466 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -111,7 +111,7 @@ jobs: - name: Extract test results id: analyze_test_results - # if: github.ref_name == 'master' + if: github.ref_name == 'master' run: | JSON_RESULTS="target/site/serenity/serenity-summary.json" CONCLUSION=failure @@ -140,7 +140,7 @@ jobs: echo "ignored=${IGNORED_TESTS}" >> $GITHUB_OUTPUT - name: Slack Notification - # if: github.ref_name == 'master' + if: github.ref_name == 'master' uses: rtCamp/action-slack-notify@v2 env: SLACK_CHANNEL: atala-qa-results