diff --git a/compatibility-kit/CHANGELOG.md b/compatibility-kit/CHANGELOG.md index f2935779d4..6c114336ff 100644 --- a/compatibility-kit/CHANGELOG.md +++ b/compatibility-kit/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +* Add a named hooked case to the Hooks suite ([#1914](https://github.com/cucumber/common/pull/1914)) + ### Changed ### Deprecated diff --git a/compatibility-kit/javascript/features/hooks/hooks.feature.ndjson b/compatibility-kit/javascript/features/hooks/hooks.feature.ndjson index 582643f67d..75a1771839 100644 --- a/compatibility-kit/javascript/features/hooks/hooks.feature.ndjson +++ b/compatibility-kit/javascript/features/hooks/hooks.feature.ndjson @@ -1,66 +1,77 @@ -{"meta":{"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"15.0.0"},"os":{"name":"linux","version":"5.11.0-34-generic"},"protocolVersion":"17.1.1","runtime":{"name":"node.js","version":"14.17.3"}}} +{"meta":{"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"15.0.0"},"os":{"name":"linux","version":"5.10.25-linuxkit"},"protocolVersion":"17.1.1","runtime":{"name":"node.js","version":"14.17.3"}}} {"source":{"data":"Feature: Hooks\n Hooks are special steps that run before or after each scenario's steps.\n They can also conditionally target specific scenarios, using tag expressions\n\n Scenario: no tags, passed step\n When a step passes\n\n Scenario: no tags, failed step\n When a step throws an exception\n\n Scenario: no tags, undefined step\n When a step throws an exception\n\n @some-tag\n Scenario: with a tag, passed step\n When a step passes\n\n @with-attachment\n Scenario: with an attachment in the hook\n When a step passes","mediaType":"text/x.cucumber.gherkin+plain","uri":"features/hooks/hooks.feature"}} -{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"7","keyword":"Scenario","location":{"column":3,"line":5},"name":"no tags, passed step","steps":[{"id":"6","keyword":"When ","location":{"column":5,"line":6},"text":"a step passes"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"9","keyword":"Scenario","location":{"column":3,"line":8},"name":"no tags, failed step","steps":[{"id":"8","keyword":"When ","location":{"column":5,"line":9},"text":"a step throws an exception"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"11","keyword":"Scenario","location":{"column":3,"line":11},"name":"no tags, undefined step","steps":[{"id":"10","keyword":"When ","location":{"column":5,"line":12},"text":"a step throws an exception"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"14","keyword":"Scenario","location":{"column":3,"line":15},"name":"with a tag, passed step","steps":[{"id":"12","keyword":"When ","location":{"column":5,"line":16},"text":"a step passes"}],"tags":[{"id":"13","location":{"column":3,"line":14},"name":"@some-tag"}]}},{"scenario":{"description":"","examples":[],"id":"17","keyword":"Scenario","location":{"column":3,"line":19},"name":"with an attachment in the hook","steps":[{"id":"15","keyword":"When ","location":{"column":5,"line":20},"text":"a step passes"}],"tags":[{"id":"16","location":{"column":3,"line":18},"name":"@with-attachment"}]}}],"description":" Hooks are special steps that run before or after each scenario's steps.\n They can also conditionally target specific scenarios, using tag expressions","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Hooks","tags":[]},"uri":"features/hooks/hooks.feature"}} -{"pickle":{"astNodeIds":["7"],"id":"19","language":"en","name":"no tags, passed step","steps":[{"astNodeIds":["6"],"id":"18","text":"a step passes"}],"tags":[],"uri":"features/hooks/hooks.feature"}} -{"pickle":{"astNodeIds":["9"],"id":"21","language":"en","name":"no tags, failed step","steps":[{"astNodeIds":["8"],"id":"20","text":"a step throws an exception"}],"tags":[],"uri":"features/hooks/hooks.feature"}} -{"pickle":{"astNodeIds":["11"],"id":"23","language":"en","name":"no tags, undefined step","steps":[{"astNodeIds":["10"],"id":"22","text":"a step throws an exception"}],"tags":[],"uri":"features/hooks/hooks.feature"}} -{"pickle":{"astNodeIds":["14"],"id":"25","language":"en","name":"with a tag, passed step","steps":[{"astNodeIds":["12"],"id":"24","text":"a step passes"}],"tags":[{"astNodeId":"13","name":"@some-tag"}],"uri":"features/hooks/hooks.feature"}} -{"pickle":{"astNodeIds":["17"],"id":"27","language":"en","name":"with an attachment in the hook","steps":[{"astNodeIds":["15"],"id":"26","text":"a step passes"}],"tags":[{"astNodeId":"16","name":"@with-attachment"}],"uri":"features/hooks/hooks.feature"}} -{"stepDefinition":{"id":"1","pattern":{"source":"a step passes","type":"CUCUMBER_EXPRESSION"},"sourceReference":{"location":{"line":8},"uri":"features/hooks/hooks.feature.ts"}}} -{"stepDefinition":{"id":"2","pattern":{"source":"a step throws an exception","type":"CUCUMBER_EXPRESSION"},"sourceReference":{"location":{"line":12},"uri":"features/hooks/hooks.feature.ts"}}} +{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"8","keyword":"Scenario","location":{"column":3,"line":5},"name":"no tags, passed step","steps":[{"id":"7","keyword":"When ","location":{"column":5,"line":6},"text":"a step passes"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"10","keyword":"Scenario","location":{"column":3,"line":8},"name":"no tags, failed step","steps":[{"id":"9","keyword":"When ","location":{"column":5,"line":9},"text":"a step throws an exception"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"12","keyword":"Scenario","location":{"column":3,"line":11},"name":"no tags, undefined step","steps":[{"id":"11","keyword":"When ","location":{"column":5,"line":12},"text":"a step throws an exception"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"15","keyword":"Scenario","location":{"column":3,"line":15},"name":"with a tag, passed step","steps":[{"id":"13","keyword":"When ","location":{"column":5,"line":16},"text":"a step passes"}],"tags":[{"id":"14","location":{"column":3,"line":14},"name":"@some-tag"}]}},{"scenario":{"description":"","examples":[],"id":"18","keyword":"Scenario","location":{"column":3,"line":19},"name":"with an attachment in the hook","steps":[{"id":"16","keyword":"When ","location":{"column":5,"line":20},"text":"a step passes"}],"tags":[{"id":"17","location":{"column":3,"line":18},"name":"@with-attachment"}]}}],"description":" Hooks are special steps that run before or after each scenario's steps.\n They can also conditionally target specific scenarios, using tag expressions","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Hooks","tags":[]},"uri":"features/hooks/hooks.feature"}} +{"pickle":{"astNodeIds":["8"],"id":"20","language":"en","name":"no tags, passed step","steps":[{"astNodeIds":["7"],"id":"19","text":"a step passes"}],"tags":[],"uri":"features/hooks/hooks.feature"}} +{"pickle":{"astNodeIds":["10"],"id":"22","language":"en","name":"no tags, failed step","steps":[{"astNodeIds":["9"],"id":"21","text":"a step throws an exception"}],"tags":[],"uri":"features/hooks/hooks.feature"}} +{"pickle":{"astNodeIds":["12"],"id":"24","language":"en","name":"no tags, undefined step","steps":[{"astNodeIds":["11"],"id":"23","text":"a step throws an exception"}],"tags":[],"uri":"features/hooks/hooks.feature"}} +{"pickle":{"astNodeIds":["15"],"id":"26","language":"en","name":"with a tag, passed step","steps":[{"astNodeIds":["13"],"id":"25","text":"a step passes"}],"tags":[{"astNodeId":"14","name":"@some-tag"}],"uri":"features/hooks/hooks.feature"}} +{"pickle":{"astNodeIds":["18"],"id":"28","language":"en","name":"with an attachment in the hook","steps":[{"astNodeIds":["16"],"id":"27","text":"a step passes"}],"tags":[{"astNodeId":"17","name":"@with-attachment"}],"uri":"features/hooks/hooks.feature"}} +{"stepDefinition":{"id":"2","pattern":{"source":"a step passes","type":"CUCUMBER_EXPRESSION"},"sourceReference":{"location":{"line":12},"uri":"features/hooks/hooks.feature.ts"}}} +{"stepDefinition":{"id":"3","pattern":{"source":"a step throws an exception","type":"CUCUMBER_EXPRESSION"},"sourceReference":{"location":{"line":16},"uri":"features/hooks/hooks.feature.ts"}}} {"hook":{"id":"0","sourceReference":{"location":{"line":4},"uri":"features/hooks/hooks.feature.ts"}}} -{"hook":{"id":"3","sourceReference":{"location":{"line":16},"uri":"features/hooks/hooks.feature.ts"}}} -{"hook":{"id":"4","sourceReference":{"location":{"line":20},"uri":"features/hooks/hooks.feature.ts"},"tagExpression":"@some-tag or @some-other-tag"}} -{"hook":{"id":"5","sourceReference":{"location":{"line":24},"uri":"features/hooks/hooks.feature.ts"},"tagExpression":"@with-attachment"}} +{"hook":{"id":"1","name":"A named hook","sourceReference":{"location":{"line":8},"uri":"features/hooks/hooks.feature.ts"}}} +{"hook":{"id":"4","sourceReference":{"location":{"line":20},"uri":"features/hooks/hooks.feature.ts"}}} +{"hook":{"id":"5","sourceReference":{"location":{"line":24},"uri":"features/hooks/hooks.feature.ts"},"tagExpression":"@some-tag or @some-other-tag"}} +{"hook":{"id":"6","sourceReference":{"location":{"line":28},"uri":"features/hooks/hooks.feature.ts"},"tagExpression":"@with-attachment"}} {"testRunStarted":{"timestamp":{"nanos":0,"seconds":0}}} -{"testCase":{"id":"31","pickleId":"19","testSteps":[{"hookId":"0","id":"28"},{"id":"29","pickleStepId":"18","stepDefinitionIds":["1"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"3","id":"30"}]}} -{"testCase":{"id":"35","pickleId":"21","testSteps":[{"hookId":"0","id":"32"},{"id":"33","pickleStepId":"20","stepDefinitionIds":["2"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"3","id":"34"}]}} -{"testCase":{"id":"39","pickleId":"23","testSteps":[{"hookId":"0","id":"36"},{"id":"37","pickleStepId":"22","stepDefinitionIds":["2"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"3","id":"38"}]}} -{"testCase":{"id":"44","pickleId":"25","testSteps":[{"hookId":"0","id":"40"},{"id":"41","pickleStepId":"24","stepDefinitionIds":["1"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"4","id":"42"},{"hookId":"3","id":"43"}]}} -{"testCase":{"id":"49","pickleId":"27","testSteps":[{"hookId":"0","id":"45"},{"id":"46","pickleStepId":"26","stepDefinitionIds":["1"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"5","id":"47"},{"hookId":"3","id":"48"}]}} -{"testCaseStarted":{"attempt":0,"id":"50","testCaseId":"31","timestamp":{"nanos":1000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"50","testStepId":"28","timestamp":{"nanos":2000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"50","testStepId":"28","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":3000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"50","testStepId":"29","timestamp":{"nanos":4000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"50","testStepId":"29","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":5000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"50","testStepId":"30","timestamp":{"nanos":6000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"50","testStepId":"30","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:5","status":"FAILED"},"timestamp":{"nanos":7000000,"seconds":0}}} -{"testCaseFinished":{"testCaseStartedId":"50","timestamp":{"nanos":8000000,"seconds":0},"willBeRetried":false}} -{"testCaseStarted":{"attempt":0,"id":"51","testCaseId":"35","timestamp":{"nanos":9000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"51","testStepId":"32","timestamp":{"nanos":10000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"51","testStepId":"32","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":11000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"51","testStepId":"33","timestamp":{"nanos":12000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"51","testStepId":"33","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in step\nfeatures/hooks/hooks.feature:9","status":"FAILED"},"timestamp":{"nanos":13000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"51","testStepId":"34","timestamp":{"nanos":14000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"51","testStepId":"34","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:8","status":"FAILED"},"timestamp":{"nanos":15000000,"seconds":0}}} -{"testCaseFinished":{"testCaseStartedId":"51","timestamp":{"nanos":16000000,"seconds":0},"willBeRetried":false}} -{"testCaseStarted":{"attempt":0,"id":"52","testCaseId":"39","timestamp":{"nanos":17000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"52","testStepId":"36","timestamp":{"nanos":18000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"52","testStepId":"36","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":19000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"52","testStepId":"37","timestamp":{"nanos":20000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"52","testStepId":"37","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in step\nfeatures/hooks/hooks.feature:12","status":"FAILED"},"timestamp":{"nanos":21000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"52","testStepId":"38","timestamp":{"nanos":22000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"52","testStepId":"38","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:11","status":"FAILED"},"timestamp":{"nanos":23000000,"seconds":0}}} -{"testCaseFinished":{"testCaseStartedId":"52","timestamp":{"nanos":24000000,"seconds":0},"willBeRetried":false}} -{"testCaseStarted":{"attempt":0,"id":"53","testCaseId":"44","timestamp":{"nanos":25000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"53","testStepId":"40","timestamp":{"nanos":26000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"53","testStepId":"40","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":27000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"53","testStepId":"41","timestamp":{"nanos":28000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"53","testStepId":"41","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":29000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"53","testStepId":"42","timestamp":{"nanos":30000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"53","testStepId":"42","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in conditional hook\nfeatures/hooks/hooks.feature:15","status":"FAILED"},"timestamp":{"nanos":31000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"53","testStepId":"43","timestamp":{"nanos":32000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"53","testStepId":"43","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:15","status":"FAILED"},"timestamp":{"nanos":33000000,"seconds":0}}} -{"testCaseFinished":{"testCaseStartedId":"53","timestamp":{"nanos":34000000,"seconds":0},"willBeRetried":false}} -{"testCaseStarted":{"attempt":0,"id":"54","testCaseId":"49","timestamp":{"nanos":35000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"54","testStepId":"45","timestamp":{"nanos":36000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"54","testStepId":"45","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":37000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"54","testStepId":"46","timestamp":{"nanos":38000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"54","testStepId":"46","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":39000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"54","testStepId":"47","timestamp":{"nanos":40000000,"seconds":0}}} -{"attachment":{"body":"PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNsYXNzPSJtbC0zIG1sLW1kLTAiIHZpZXdCb3g9IjAgMCA0MC41OSA0Ni4zMSIgd2lkdGg9IjQwLjU5IiBoZWlnaHQ9IjQ2LjMxIj4KICAgIDxnPgogICAgICAgIDxwYXRoIGZpbGw9IiMyM2Q5NmMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTMwLjI4MyAzLjY0NXEtLjUyOC0uMzE3LTEuMDgtLjU5M2ExNi4xNjQgMTYuMTY0IDAgMDAtMS4xNTQtLjUxOGMtLjEyNC0uMDUyLS4yNDctLjEtLjM3Mi0uMTQ5LS4zNDMtLjEyNy0uNjg5LS4yNjgtMS4wNDItLjM3MWExOS40MjcgMTkuNDI3IDAgMTAtOS43OTIgMzcuNTF2NS41NmMxMS42NzYtMS43NTMgMjIuMDE2LTEwLjk3OSAyMi43ODctMjMuMDkzLjQ1OS03LjI4OS0zLjE5My0xNC43My05LjM0Ny0xOC4zNDZ6Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iIzE3MzY0NyIgZD0iTTE1Ljc4NyA0Ni4zMDd2LTUuOTM1QTIwLjQ3MiAyMC40NzIgMCAxMTI2Ljk1OSAxLjAxNWMuMjc0LjA4LjU1Ny4xODcuODMyLjI5MWwuMjQ4LjA5M2MuMTY1LjA2NC4yOTEuMTEzLjQxNy4xNjcuMzQ4LjEzNy43MzkuMzEzIDEuMjA4LjU0M3EuNTg5LjI5NSAxLjE1My42MzNjNi4zOTMgMy43NTYgMTAuMzU0IDExLjUxOCA5Ljg1NyAxOS4zMTYtLjc2MyAxMi0xMC43MjIgMjIuMTIyLTIzLjY3OSAyNC4wNjd6bTQuOC00NC4yMTRoLS4wMjZhMTguMzY2IDE4LjM2NiAwIDAwLTMuNTI0IDM2LjQwOGwuODUuMTY1djUuMThjMTEuMzkyLTIuMjI0IDIwLjAwOS0xMS4yNzIgMjAuNjg2LTIxLjkyMi40NDgtNy4wMzMtMy4xLTE0LjAxOC04LjgzLTE3LjM4M2wtLjAwOC0uMDA1QTE0LjY5MSAxNC42OTEgMCAwMDI3LjY1NCAzLjVhNS43NCA1Ljc0IDAgMDAtLjM0NC0uMTM4bC0uMjctLjFhOS40OSA5LjQ5IDAgMDAtLjcwOC0uMjQ5IDE4LjQyNSAxOC40MjUgMCAwMC01Ljc0My0uOTJ6Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iIzE3MzY0NyIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTYuNjY2IDEwLjU4YTEuOCAxLjggMCAwMTEuNTgzLjYwOCA0LjE4NCA0LjE4NCAwIDAxLjcyOCAxLjEwN2MuNjQ1IDEuNDIyIDEuMDI3IDMuNDYxLjIzIDQuNjA1YTYuMzM0IDYuMzM0IDAgMDEtMy45ODEtMy4wODcgMy4yMzYgMy4yMzYgMCAwMS0uMzQ3LTEuMzM5IDEuOTU3IDEuOTU3IDAgMDExLjc4Ny0xLjg5NHptLTUuNjgzIDguMDI1YTcuNzQyIDcuNzQyIDAgMDAxLjIxOC43MzcgNS43ODkgNS43ODkgMCAwMDQuODgzLS4xMzggNi4xMTYgNi4xMTYgMCAwMC0zLjM0NS0zLjQ1IDMuNjY0IDMuNjY0IDAgMDAtMS40NDItLjMyMSAxLjg4NCAxLjg4NCAwIDAwLS4zMTkgMCAxLjc2NiAxLjc2NiAwIDAwLS45OTUgMy4xNzJ6bTYuMSAzLjQzM2MtLjc3Ny0uNTE4LTIuMzc5LS4zMDktMy4zMTItLjI5MmE0LjQxNiA0LjQxNiAwIDAwLTEuNjY2LjM1MiAzLjUgMy41IDAgMDAtMS4yMTguNzM4IDEuODE3IDEuODE3IDAgMDAxLjQwOSAzLjE3MSAzLjMgMy4zIDAgMDAxLjQ0Mi0uMzIxYzEuNDM2LS42MiAzLjE0MS0yLjMyIDMuMzQ2LTMuNjQ4em0yLjYxIDJhNi41NTYgNi41NTYgMCAwMC0zLjcyNCAzLjUwNiAzLjA5MSAzLjA5MSAwIDAwLS4zMjEgMS4zMTQgMS45MDcgMS45MDcgMCAwMDMuMyAxLjM0NiA3LjQyMiA3LjQyMiAwIDAwLjctMS4yMThjLjYyMS0xLjMzMy44NjYtMy43Mi4wNDYtNC45NDh6bTIuNTU3LTcuMTY3YTUuOTQxIDUuOTQxIDAgMDAzLjctMy4xNjcgMy4yNDMgMy4yNDMgMCAwMC4zMTktMS4zNDYgMS45MTUgMS45MTUgMCAwMC0xLjc5NC0xLjk1NCAxLjgzMiAxLjgzMiAwIDAwLTEuNi42NDEgNy4zODIgNy4zODIgMCAwMC0uNzA1IDEuMjE4Yy0uNjIgMS40MzQtLjg0MiAzLjQ4LjA4MSA0LjYwM3ptNC4yMDggMTIuMTE1YTMuMjQ0IDMuMjQ0IDAgMDAtLjMyMS0xLjM0NSA1Ljg2OSA1Ljg2OSAwIDAwLTMuNTU0LTMuMjY5IDUuMzg2IDUuMzg2IDAgMDAtLjIyNiA0LjcxMSA0LjE0NyA0LjE0NyAwIDAwLjcgMS4xMjFjMS4xMzMgMS4yMyAzLjUwNS4zMiAzLjQwMi0xLjIxOHptNC4yLTYuMjhhNy40NjYgNy40NjYgMCAwMC0xLjIxNy0uNyA0LjQyNSA0LjQyNSAwIDAwLTEuNjY2LS4zNTIgNi40IDYuNCAwIDAwLTMuMTg4LjU1NSA1Ljk1OSA1Ljk1OSAwIDAwMy4zMTYgMy4zODYgMy42NzIgMy42NzIgMCAwMDEuNDQyLjMyIDEuOCAxLjggMCAwMDEuMzEtMy4yMDl6Ii8+CiAgICA8L2c+Cjwvc3ZnPg==","contentEncoding":"BASE64","mediaType":"image/svg+xml","testCaseStartedId":"54","testStepId":"47"}} -{"testStepFinished":{"testCaseStartedId":"54","testStepId":"47","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":41000000,"seconds":0}}} -{"testStepStarted":{"testCaseStartedId":"54","testStepId":"48","timestamp":{"nanos":42000000,"seconds":0}}} -{"testStepFinished":{"testCaseStartedId":"54","testStepId":"48","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:19","status":"FAILED"},"timestamp":{"nanos":43000000,"seconds":0}}} -{"testCaseFinished":{"testCaseStartedId":"54","timestamp":{"nanos":44000000,"seconds":0},"willBeRetried":false}} -{"testRunFinished":{"success":false,"timestamp":{"nanos":45000000,"seconds":0}}} +{"testCase":{"id":"33","pickleId":"20","testSteps":[{"hookId":"0","id":"29"},{"hookId":"1","id":"30"},{"id":"31","pickleStepId":"19","stepDefinitionIds":["2"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"4","id":"32"}]}} +{"testCase":{"id":"38","pickleId":"22","testSteps":[{"hookId":"0","id":"34"},{"hookId":"1","id":"35"},{"id":"36","pickleStepId":"21","stepDefinitionIds":["3"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"4","id":"37"}]}} +{"testCase":{"id":"43","pickleId":"24","testSteps":[{"hookId":"0","id":"39"},{"hookId":"1","id":"40"},{"id":"41","pickleStepId":"23","stepDefinitionIds":["3"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"4","id":"42"}]}} +{"testCase":{"id":"49","pickleId":"26","testSteps":[{"hookId":"0","id":"44"},{"hookId":"1","id":"45"},{"id":"46","pickleStepId":"25","stepDefinitionIds":["2"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"5","id":"47"},{"hookId":"4","id":"48"}]}} +{"testCase":{"id":"55","pickleId":"28","testSteps":[{"hookId":"0","id":"50"},{"hookId":"1","id":"51"},{"id":"52","pickleStepId":"27","stepDefinitionIds":["2"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]},{"hookId":"6","id":"53"},{"hookId":"4","id":"54"}]}} +{"testCaseStarted":{"attempt":0,"id":"56","testCaseId":"33","timestamp":{"nanos":1000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"56","testStepId":"29","timestamp":{"nanos":2000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"56","testStepId":"29","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":3000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"56","testStepId":"30","timestamp":{"nanos":4000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"56","testStepId":"30","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":5000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"56","testStepId":"31","timestamp":{"nanos":6000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"56","testStepId":"31","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":7000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"56","testStepId":"32","timestamp":{"nanos":8000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"56","testStepId":"32","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:5","status":"FAILED"},"timestamp":{"nanos":9000000,"seconds":0}}} +{"testCaseFinished":{"testCaseStartedId":"56","timestamp":{"nanos":10000000,"seconds":0},"willBeRetried":false}} +{"testCaseStarted":{"attempt":0,"id":"57","testCaseId":"38","timestamp":{"nanos":11000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"57","testStepId":"34","timestamp":{"nanos":12000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"57","testStepId":"34","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":13000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"57","testStepId":"35","timestamp":{"nanos":14000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"57","testStepId":"35","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":15000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"57","testStepId":"36","timestamp":{"nanos":16000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"57","testStepId":"36","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in step\nfeatures/hooks/hooks.feature:9","status":"FAILED"},"timestamp":{"nanos":17000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"57","testStepId":"37","timestamp":{"nanos":18000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"57","testStepId":"37","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:8","status":"FAILED"},"timestamp":{"nanos":19000000,"seconds":0}}} +{"testCaseFinished":{"testCaseStartedId":"57","timestamp":{"nanos":20000000,"seconds":0},"willBeRetried":false}} +{"testCaseStarted":{"attempt":0,"id":"58","testCaseId":"43","timestamp":{"nanos":21000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"58","testStepId":"39","timestamp":{"nanos":22000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"58","testStepId":"39","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":23000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"58","testStepId":"40","timestamp":{"nanos":24000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"58","testStepId":"40","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":25000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"58","testStepId":"41","timestamp":{"nanos":26000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"58","testStepId":"41","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in step\nfeatures/hooks/hooks.feature:12","status":"FAILED"},"timestamp":{"nanos":27000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"58","testStepId":"42","timestamp":{"nanos":28000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"58","testStepId":"42","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:11","status":"FAILED"},"timestamp":{"nanos":29000000,"seconds":0}}} +{"testCaseFinished":{"testCaseStartedId":"58","timestamp":{"nanos":30000000,"seconds":0},"willBeRetried":false}} +{"testCaseStarted":{"attempt":0,"id":"59","testCaseId":"49","timestamp":{"nanos":31000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"59","testStepId":"44","timestamp":{"nanos":32000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"59","testStepId":"44","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":33000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"59","testStepId":"45","timestamp":{"nanos":34000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"59","testStepId":"45","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":35000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"59","testStepId":"46","timestamp":{"nanos":36000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"59","testStepId":"46","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":37000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"59","testStepId":"47","timestamp":{"nanos":38000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"59","testStepId":"47","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in conditional hook\nfeatures/hooks/hooks.feature:15","status":"FAILED"},"timestamp":{"nanos":39000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"59","testStepId":"48","timestamp":{"nanos":40000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"59","testStepId":"48","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:15","status":"FAILED"},"timestamp":{"nanos":41000000,"seconds":0}}} +{"testCaseFinished":{"testCaseStartedId":"59","timestamp":{"nanos":42000000,"seconds":0},"willBeRetried":false}} +{"testCaseStarted":{"attempt":0,"id":"60","testCaseId":"55","timestamp":{"nanos":43000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"60","testStepId":"50","timestamp":{"nanos":44000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"60","testStepId":"50","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":45000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"60","testStepId":"51","timestamp":{"nanos":46000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"60","testStepId":"51","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":47000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"60","testStepId":"52","timestamp":{"nanos":48000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"60","testStepId":"52","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":49000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"60","testStepId":"53","timestamp":{"nanos":50000000,"seconds":0}}} +{"attachment":{"body":"PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNsYXNzPSJtbC0zIG1sLW1kLTAiIHZpZXdCb3g9IjAgMCA0MC41OSA0Ni4zMSIgd2lkdGg9IjQwLjU5IiBoZWlnaHQ9IjQ2LjMxIj4KICAgIDxnPgogICAgICAgIDxwYXRoIGZpbGw9IiMyM2Q5NmMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTMwLjI4MyAzLjY0NXEtLjUyOC0uMzE3LTEuMDgtLjU5M2ExNi4xNjQgMTYuMTY0IDAgMDAtMS4xNTQtLjUxOGMtLjEyNC0uMDUyLS4yNDctLjEtLjM3Mi0uMTQ5LS4zNDMtLjEyNy0uNjg5LS4yNjgtMS4wNDItLjM3MWExOS40MjcgMTkuNDI3IDAgMTAtOS43OTIgMzcuNTF2NS41NmMxMS42NzYtMS43NTMgMjIuMDE2LTEwLjk3OSAyMi43ODctMjMuMDkzLjQ1OS03LjI4OS0zLjE5My0xNC43My05LjM0Ny0xOC4zNDZ6Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iIzE3MzY0NyIgZD0iTTE1Ljc4NyA0Ni4zMDd2LTUuOTM1QTIwLjQ3MiAyMC40NzIgMCAxMTI2Ljk1OSAxLjAxNWMuMjc0LjA4LjU1Ny4xODcuODMyLjI5MWwuMjQ4LjA5M2MuMTY1LjA2NC4yOTEuMTEzLjQxNy4xNjcuMzQ4LjEzNy43MzkuMzEzIDEuMjA4LjU0M3EuNTg5LjI5NSAxLjE1My42MzNjNi4zOTMgMy43NTYgMTAuMzU0IDExLjUxOCA5Ljg1NyAxOS4zMTYtLjc2MyAxMi0xMC43MjIgMjIuMTIyLTIzLjY3OSAyNC4wNjd6bTQuOC00NC4yMTRoLS4wMjZhMTguMzY2IDE4LjM2NiAwIDAwLTMuNTI0IDM2LjQwOGwuODUuMTY1djUuMThjMTEuMzkyLTIuMjI0IDIwLjAwOS0xMS4yNzIgMjAuNjg2LTIxLjkyMi40NDgtNy4wMzMtMy4xLTE0LjAxOC04LjgzLTE3LjM4M2wtLjAwOC0uMDA1QTE0LjY5MSAxNC42OTEgMCAwMDI3LjY1NCAzLjVhNS43NCA1Ljc0IDAgMDAtLjM0NC0uMTM4bC0uMjctLjFhOS40OSA5LjQ5IDAgMDAtLjcwOC0uMjQ5IDE4LjQyNSAxOC40MjUgMCAwMC01Ljc0My0uOTJ6Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iIzE3MzY0NyIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTYuNjY2IDEwLjU4YTEuOCAxLjggMCAwMTEuNTgzLjYwOCA0LjE4NCA0LjE4NCAwIDAxLjcyOCAxLjEwN2MuNjQ1IDEuNDIyIDEuMDI3IDMuNDYxLjIzIDQuNjA1YTYuMzM0IDYuMzM0IDAgMDEtMy45ODEtMy4wODcgMy4yMzYgMy4yMzYgMCAwMS0uMzQ3LTEuMzM5IDEuOTU3IDEuOTU3IDAgMDExLjc4Ny0xLjg5NHptLTUuNjgzIDguMDI1YTcuNzQyIDcuNzQyIDAgMDAxLjIxOC43MzcgNS43ODkgNS43ODkgMCAwMDQuODgzLS4xMzggNi4xMTYgNi4xMTYgMCAwMC0zLjM0NS0zLjQ1IDMuNjY0IDMuNjY0IDAgMDAtMS40NDItLjMyMSAxLjg4NCAxLjg4NCAwIDAwLS4zMTkgMCAxLjc2NiAxLjc2NiAwIDAwLS45OTUgMy4xNzJ6bTYuMSAzLjQzM2MtLjc3Ny0uNTE4LTIuMzc5LS4zMDktMy4zMTItLjI5MmE0LjQxNiA0LjQxNiAwIDAwLTEuNjY2LjM1MiAzLjUgMy41IDAgMDAtMS4yMTguNzM4IDEuODE3IDEuODE3IDAgMDAxLjQwOSAzLjE3MSAzLjMgMy4zIDAgMDAxLjQ0Mi0uMzIxYzEuNDM2LS42MiAzLjE0MS0yLjMyIDMuMzQ2LTMuNjQ4em0yLjYxIDJhNi41NTYgNi41NTYgMCAwMC0zLjcyNCAzLjUwNiAzLjA5MSAzLjA5MSAwIDAwLS4zMjEgMS4zMTQgMS45MDcgMS45MDcgMCAwMDMuMyAxLjM0NiA3LjQyMiA3LjQyMiAwIDAwLjctMS4yMThjLjYyMS0xLjMzMy44NjYtMy43Mi4wNDYtNC45NDh6bTIuNTU3LTcuMTY3YTUuOTQxIDUuOTQxIDAgMDAzLjctMy4xNjcgMy4yNDMgMy4yNDMgMCAwMC4zMTktMS4zNDYgMS45MTUgMS45MTUgMCAwMC0xLjc5NC0xLjk1NCAxLjgzMiAxLjgzMiAwIDAwLTEuNi42NDEgNy4zODIgNy4zODIgMCAwMC0uNzA1IDEuMjE4Yy0uNjIgMS40MzQtLjg0MiAzLjQ4LjA4MSA0LjYwM3ptNC4yMDggMTIuMTE1YTMuMjQ0IDMuMjQ0IDAgMDAtLjMyMS0xLjM0NSA1Ljg2OSA1Ljg2OSAwIDAwLTMuNTU0LTMuMjY5IDUuMzg2IDUuMzg2IDAgMDAtLjIyNiA0LjcxMSA0LjE0NyA0LjE0NyAwIDAwLjcgMS4xMjFjMS4xMzMgMS4yMyAzLjUwNS4zMiAzLjQwMi0xLjIxOHptNC4yLTYuMjhhNy40NjYgNy40NjYgMCAwMC0xLjIxNy0uNyA0LjQyNSA0LjQyNSAwIDAwLTEuNjY2LS4zNTIgNi40IDYuNCAwIDAwLTMuMTg4LjU1NSA1Ljk1OSA1Ljk1OSAwIDAwMy4zMTYgMy4zODYgMy42NzIgMy42NzIgMCAwMDEuNDQyLjMyIDEuOCAxLjggMCAwMDEuMzEtMy4yMDl6Ii8+CiAgICA8L2c+Cjwvc3ZnPg==","contentEncoding":"BASE64","mediaType":"image/svg+xml","testCaseStartedId":"60","testStepId":"53"}} +{"testStepFinished":{"testCaseStartedId":"60","testStepId":"53","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"status":"PASSED"},"timestamp":{"nanos":51000000,"seconds":0}}} +{"testStepStarted":{"testCaseStartedId":"60","testStepId":"54","timestamp":{"nanos":52000000,"seconds":0}}} +{"testStepFinished":{"testCaseStartedId":"60","testStepId":"54","testStepResult":{"duration":{"nanos":1000000,"seconds":0},"message":"Exception in hook\nfeatures/hooks/hooks.feature:19","status":"FAILED"},"timestamp":{"nanos":53000000,"seconds":0}}} +{"testCaseFinished":{"testCaseStartedId":"60","timestamp":{"nanos":54000000,"seconds":0},"willBeRetried":false}} +{"testRunFinished":{"success":false,"timestamp":{"nanos":55000000,"seconds":0}}} diff --git a/compatibility-kit/javascript/features/hooks/hooks.feature.ts b/compatibility-kit/javascript/features/hooks/hooks.feature.ts index ce0f41d9b1..632190cf7b 100644 --- a/compatibility-kit/javascript/features/hooks/hooks.feature.ts +++ b/compatibility-kit/javascript/features/hooks/hooks.feature.ts @@ -5,6 +5,10 @@ Before(function () { // no-op }) +Before({name: 'A named hook'}, function () { + // no-op +}) + When('a step passes', function () { // no-op }) diff --git a/compatibility-kit/ruby/features/hooks/hooks.feature.rb b/compatibility-kit/ruby/features/hooks/hooks.feature.rb index 974c349479..0f5d59184b 100644 --- a/compatibility-kit/ruby/features/hooks/hooks.feature.rb +++ b/compatibility-kit/ruby/features/hooks/hooks.feature.rb @@ -7,6 +7,11 @@ def attach_or_embed(world, data, media_type) # no-op end +Before do + # This is the equivalent of the new named hook in typescript + # no-op +end + When('a step passes') do # no-op end diff --git a/compatibility-kit/ruby/scripts/neutralize-json b/compatibility-kit/ruby/scripts/neutralize-json index 5d031111d6..354012a176 100755 --- a/compatibility-kit/ruby/scripts/neutralize-json +++ b/compatibility-kit/ruby/scripts/neutralize-json @@ -12,4 +12,4 @@ set -euf -o pipefail jq "del(.[].elements[]?.before[]?.result.duration)" | \ jq "del(.[].elements[]?.steps[]?.result.duration)" | \ jq "del(.[].elements[]?.after[]?.result.duration)" | \ -jq +jq "." diff --git a/compatibility-kit/ruby/scripts/neutralize-json-cross-language b/compatibility-kit/ruby/scripts/neutralize-json-cross-language index 3bfab35164..f29af4852e 100755 --- a/compatibility-kit/ruby/scripts/neutralize-json-cross-language +++ b/compatibility-kit/ruby/scripts/neutralize-json-cross-language @@ -20,4 +20,4 @@ jq "del(.[].elements[]?.after[]?.result.duration)" | \ jq ".[].elements[]?.after[]?.result.error_message = \"some after hook error\"" | \ jq ".[].elements[]?.after[]?.match.location = \"some_after_hook.xyz\"" | \ -jq \ No newline at end of file +jq "." \ No newline at end of file diff --git a/fake-cucumber/CHANGELOG.md b/fake-cucumber/CHANGELOG.md index 9d368a3067..1f72677c3e 100644 --- a/fake-cucumber/CHANGELOG.md +++ b/fake-cucumber/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +* Ability to provide a name for `Before` and `After` hooks ([#1914](https://github.com/cucumber/common/pull/1914)) + ### Changed ### Deprecated diff --git a/fake-cucumber/javascript/src/Hook.ts b/fake-cucumber/javascript/src/Hook.ts index 4b7f956d51..cfbf705b4e 100644 --- a/fake-cucumber/javascript/src/Hook.ts +++ b/fake-cucumber/javascript/src/Hook.ts @@ -8,7 +8,8 @@ export default class Hook implements IHook { public readonly id: string, private readonly tagExpression: string | null, private readonly sourceReference: messages.SourceReference, - private readonly body: AnyBody + private readonly body: AnyBody, + private readonly name?: string ) {} public match(pickle: messages.Pickle): ISupportCodeExecutor | null { @@ -23,6 +24,10 @@ export default class Hook implements IHook { sourceReference: this.sourceReference, } + if (this.name) { + hook.name = this.name + } + if (this.tagExpression) { hook.tagExpression = this.tagExpression } diff --git a/fake-cucumber/javascript/src/SupportCode.ts b/fake-cucumber/javascript/src/SupportCode.ts index 5a2e8618af..ec69fe961d 100644 --- a/fake-cucumber/javascript/src/SupportCode.ts +++ b/fake-cucumber/javascript/src/SupportCode.ts @@ -4,7 +4,7 @@ import { ParameterTypeRegistry, } from '@cucumber/cucumber-expressions' import * as messages from '@cucumber/messages' -import { IHook, AnyBody, IStepDefinition } from './types' +import { IHook, AnyBody, IStepDefinition, HookOptions } from './types' import ExpressionStepDefinition from './ExpressionStepDefinition' import Hook from './Hook' import IClock from './IClock' @@ -90,10 +90,10 @@ export default class SupportCode { public defineBeforeHook( sourceReference: messages.SourceReference, - tagExpressionOrBody: string | AnyBody, + tagExpressionOptionsOrBody: string | HookOptions | AnyBody, body?: AnyBody ) { - this.registerBeforeHook(this.makeHook(sourceReference, tagExpressionOrBody, body)) + this.registerBeforeHook(this.makeHook(sourceReference, tagExpressionOptionsOrBody, body)) } public registerBeforeHook(hook: IHook) { @@ -102,10 +102,10 @@ export default class SupportCode { public defineAfterHook( sourceReference: messages.SourceReference, - tagExpressionOrBody: string | AnyBody, + tagExpressionOptionsOrBody: string | HookOptions | AnyBody, body?: AnyBody ) { - this.registerAfterHook(this.makeHook(sourceReference, tagExpressionOrBody, body)) + this.registerAfterHook(this.makeHook(sourceReference, tagExpressionOptionsOrBody, body)) } public registerAfterHook(hook: IHook) { @@ -114,11 +114,18 @@ export default class SupportCode { private makeHook( sourceReference: messages.SourceReference, - tagExpressionOrBody: string | AnyBody, + tagExpressionOptionsOrBody: string | HookOptions | AnyBody, body?: AnyBody ) { - const tagExpression = typeof tagExpressionOrBody === 'string' ? tagExpressionOrBody : null - body = typeof tagExpressionOrBody !== 'string' ? tagExpressionOrBody : body - return new Hook(this.newId(), tagExpression, sourceReference, body) + const name = + typeof tagExpressionOptionsOrBody === 'object' ? tagExpressionOptionsOrBody.name : undefined + let tagExpression = null + if (typeof tagExpressionOptionsOrBody === 'string') { + tagExpression = tagExpressionOptionsOrBody + } else if (typeof tagExpressionOptionsOrBody === 'object') { + tagExpression = tagExpressionOptionsOrBody.tagExpression ?? null + } + body = typeof tagExpressionOptionsOrBody === 'function' ? tagExpressionOptionsOrBody : body + return new Hook(this.newId(), tagExpression, sourceReference, body, name) } } diff --git a/fake-cucumber/javascript/src/dsl.ts b/fake-cucumber/javascript/src/dsl.ts index 5c62d9229e..07a612ceb5 100644 --- a/fake-cucumber/javascript/src/dsl.ts +++ b/fake-cucumber/javascript/src/dsl.ts @@ -1,5 +1,5 @@ import SupportCode from './SupportCode' -import { AnyBody } from './types' +import { AnyBody, HookOptions } from './types' import * as messages from '@cucumber/messages' import StackUtils from 'stack-utils' import IParameterTypeDefinition from './IParameterTypeDefinition' @@ -15,7 +15,7 @@ function defineStepDefinition(expression: string | RegExp, body: AnyBody) { global.supportCode.defineStepDefinition(getSourceReference(new Error().stack), expression, body) } -function defineBeforeHook(tagExpressionOrBody: string | AnyBody, body?: AnyBody) { +function defineBeforeHook(tagExpressionOrBody: string | HookOptions | AnyBody, body?: AnyBody) { //@ts-ignore global.supportCode.defineBeforeHook( getSourceReference(new Error().stack), @@ -24,7 +24,7 @@ function defineBeforeHook(tagExpressionOrBody: string | AnyBody, body?: AnyBody) ) } -function defineAfterHook(tagExpressionOrBody: string | AnyBody, body?: AnyBody) { +function defineAfterHook(tagExpressionOrBody: string | HookOptions | AnyBody, body?: AnyBody) { //@ts-ignore global.supportCode.defineAfterHook( getSourceReference(new Error().stack), diff --git a/fake-cucumber/javascript/src/types.ts b/fake-cucumber/javascript/src/types.ts index 7fef2a8db5..ea76759bc3 100644 --- a/fake-cucumber/javascript/src/types.ts +++ b/fake-cucumber/javascript/src/types.ts @@ -67,6 +67,10 @@ export interface ITestCase { } export type EnvelopeListener = (envelope: messages.Envelope) => void +export interface HookOptions { + name?: string + tagExpression?: string +} export type AnyBody = (...args: readonly unknown[]) => unknown export type Attach = (data: string | Buffer | Readable, mediaType: string) => void | Promise export type Log = (text: string) => void | Promise diff --git a/json-formatter/ruby-testdata/neutralize-json b/json-formatter/ruby-testdata/neutralize-json index 439f3b9210..47e772c760 100755 --- a/json-formatter/ruby-testdata/neutralize-json +++ b/json-formatter/ruby-testdata/neutralize-json @@ -22,4 +22,4 @@ jq ".[].elements[]?.after[]?.result.duration = 99" | \ jq ".[].elements[]?.after[]?.result.error_message = \"some after hook error\"" | \ jq ".[].elements[]?.after[]?.match.location = \"some_after_hook.xyz\"" | \ -jq +jq "." diff --git a/messages/CHANGELOG.md b/messages/CHANGELOG.md index 866aaafc35..648b810cba 100644 --- a/messages/CHANGELOG.md +++ b/messages/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * Support for EcmaScript modules (aka ESM) ([#1756](https://github.com/cucumber/common/pull/1756)) +* New optional `name` property on the Hook schema ([#1914](https://github.com/cucumber/common/pull/1914)) ### Changed diff --git a/messages/go/messages.go b/messages/go/messages.go index f6b9c89d2d..22146d61e8 100644 --- a/messages/go/messages.go +++ b/messages/go/messages.go @@ -149,6 +149,7 @@ type Tag struct { type Hook struct { Id string `json:"id"` + Name string `json:"name,omitempty"` SourceReference *SourceReference `json:"sourceReference"` TagExpression string `json:"tagExpression,omitempty"` } diff --git a/messages/java/src/generated/java/io/cucumber/messages/types/Hook.java b/messages/java/src/generated/java/io/cucumber/messages/types/Hook.java index bdfa6dfeff..c87ac4d1db 100644 --- a/messages/java/src/generated/java/io/cucumber/messages/types/Hook.java +++ b/messages/java/src/generated/java/io/cucumber/messages/types/Hook.java @@ -11,15 +11,18 @@ @SuppressWarnings("unused") public final class Hook { private final String id; + private final String name; private final SourceReference sourceReference; private final String tagExpression; public Hook( String id, + String name, SourceReference sourceReference, String tagExpression ) { this.id = requireNonNull(id, "Hook.id cannot be null"); + this.name = name; this.sourceReference = requireNonNull(sourceReference, "Hook.sourceReference cannot be null"); this.tagExpression = tagExpression; } @@ -28,6 +31,10 @@ public String getId() { return id; } + public Optional getName() { + return Optional.ofNullable(name); + } + public SourceReference getSourceReference() { return sourceReference; } @@ -43,6 +50,7 @@ public boolean equals(Object o) { Hook that = (Hook) o; return id.equals(that.id) && + Objects.equals(name, that.name) && sourceReference.equals(that.sourceReference) && Objects.equals(tagExpression, that.tagExpression); } @@ -51,6 +59,7 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash( id, + name, sourceReference, tagExpression ); @@ -60,6 +69,7 @@ public int hashCode() { public String toString() { return "Hook{" + "id=" + id + + ", name=" + name + ", sourceReference=" + sourceReference + ", tagExpression=" + tagExpression + '}'; diff --git a/messages/javascript/src/messages.ts b/messages/javascript/src/messages.ts index 16926069a9..fdfb697aab 100644 --- a/messages/javascript/src/messages.ts +++ b/messages/javascript/src/messages.ts @@ -297,6 +297,8 @@ export class Hook { id: string = '' + name?: string + @Type(() => SourceReference) sourceReference: SourceReference = new SourceReference() diff --git a/messages/jsonschema/Hook.json b/messages/jsonschema/Hook.json index 7c0afcd776..6e64289bc5 100644 --- a/messages/jsonschema/Hook.json +++ b/messages/jsonschema/Hook.json @@ -10,6 +10,9 @@ "id": { "type": "string" }, + "name": { + "type": "string" + }, "sourceReference": { "$ref": "./SourceReference.json" }, diff --git a/messages/messages.md b/messages/messages.md index 10209365d6..1f2b425aa1 100644 --- a/messages/messages.md +++ b/messages/messages.md @@ -191,6 +191,7 @@ will only have one of its fields set, which indicates the payload of the message | Field | Type | Required | Description | | ----- | ---- | ----------- | ----------- | | `id` | string | yes | | +| `name` | string | no | | | `sourceReference` | [SourceReference](#sourcereference) | yes | | | `tagExpression` | string | no | | diff --git a/messages/perl/lib/Cucumber/Messages.pm b/messages/perl/lib/Cucumber/Messages.pm index 4263bc765f..ecab716524 100644 --- a/messages/perl/lib/Cucumber/Messages.pm +++ b/messages/perl/lib/Cucumber/Messages.pm @@ -1913,6 +1913,7 @@ use Scalar::Util qw( blessed ); my %types = ( id => 'string', + name => 'string', source_reference => 'Cucumber::Messages::SourceReference', tag_expression => 'string', ); @@ -1937,6 +1938,16 @@ has id => ); +=head4 name + + +=cut + +has name => + (is => 'ro', + ); + + =head4 source_reference diff --git a/messages/php/src-generated/Hook.php b/messages/php/src-generated/Hook.php index f7db210a32..75de7f5c25 100644 --- a/messages/php/src-generated/Hook.php +++ b/messages/php/src-generated/Hook.php @@ -26,6 +26,7 @@ final class Hook implements JsonSerializable */ public function __construct( public readonly string $id = '', + public readonly ?string $name = null, public readonly SourceReference $sourceReference = new SourceReference(), public readonly ?string $tagExpression = null, ) { @@ -39,11 +40,13 @@ public function __construct( public static function fromArray(array $arr): self { self::ensureId($arr); + self::ensureName($arr); self::ensureSourceReference($arr); self::ensureTagExpression($arr); return new self( (string) $arr['id'], + isset($arr['name']) ? (string) $arr['name'] : null, SourceReference::fromArray($arr['sourceReference']), isset($arr['tagExpression']) ? (string) $arr['tagExpression'] : null, ); @@ -62,6 +65,16 @@ private static function ensureId(array $arr): void } } + /** + * @psalm-assert array{name?: string|int|bool} $arr + */ + private static function ensureName(array $arr): void + { + if (array_key_exists('name', $arr) && is_array($arr['name'])) { + throw new SchemaViolationException('Property \'name\' was array'); + } + } + /** * @psalm-assert array{sourceReference: array} $arr */ diff --git a/messages/ruby/lib/cucumber/messages.deserializers.rb b/messages/ruby/lib/cucumber/messages.deserializers.rb index 26307f78d9..61e4a03a31 100644 --- a/messages/ruby/lib/cucumber/messages.deserializers.rb +++ b/messages/ruby/lib/cucumber/messages.deserializers.rb @@ -439,6 +439,7 @@ def self.from_h(hash) self.new( id: hash[:id], + name: hash[:name], source_reference: SourceReference.from_h(hash[:sourceReference]), tag_expression: hash[:tagExpression], ) diff --git a/messages/ruby/lib/cucumber/messages.dtos.rb b/messages/ruby/lib/cucumber/messages.dtos.rb index b3dd2eb96a..5447cdf4a4 100644 --- a/messages/ruby/lib/cucumber/messages.dtos.rb +++ b/messages/ruby/lib/cucumber/messages.dtos.rb @@ -794,16 +794,20 @@ class Hook < ::Cucumber::Messages::Message attr_reader :id + attr_reader :name + attr_reader :source_reference attr_reader :tag_expression def initialize( id: '', + name: nil, source_reference: SourceReference.new, tag_expression: nil ) @id = id + @name = name @source_reference = source_reference @tag_expression = tag_expression end