@@ -18,6 +18,7 @@ import {
1818import {
1919 ITaskFrontendTrackingError ,
2020 ITaskSpecEnvelopes ,
21+ ITaskSuggestion ,
2122 ITaskTestCaseFinished ,
2223 ITaskTestCaseStarted ,
2324 ITaskTestRunHookFinished ,
@@ -26,6 +27,7 @@ import {
2627 ITaskTestStepStarted ,
2728 TASK_FRONTEND_TRACKING_ERROR ,
2829 TASK_SPEC_ENVELOPES ,
30+ TASK_SUGGESTION ,
2931 TASK_TEST_CASE_FINISHED ,
3032 TASK_TEST_CASE_STARTED ,
3133 TASK_TEST_RUN_HOOK_FINISHED ,
@@ -273,6 +275,12 @@ function taskFrontEndTrackingError(error: CypressCucumberAssertionError) {
273275 ) ;
274276}
275277
278+ function taskSuggestion ( suggestion : messages . Suggestion ) {
279+ return cy . task ( TASK_SUGGESTION , suggestion satisfies ITaskSuggestion , {
280+ log : false ,
281+ } ) ;
282+ }
283+
276284function emitSkippedPickle (
277285 context : CompositionContext ,
278286 pickle : messages . Pickle ,
@@ -862,60 +870,94 @@ function createPickle(context: CompositionContext, pickle: messages.Pickle) {
862870
863871 return beforeHooksChain ( )
864872 . then ( ( beforeStepHookResults ) => {
865- try {
866- return runStepWithLogGroup ( {
867- keyword : ensure (
868- "keyword" in scenarioStep && scenarioStep . keyword ,
869- "Expected to find a keyword in the scenario step" ,
870- ) ,
871- argument,
872- text,
873- fn : ( ) => {
874- try {
875- return registry . runStepDefinition (
876- this ,
877- text ,
878- dryRun ,
879- argument ,
880- ) ;
881- } catch ( e ) {
882- if (
883- e instanceof MissingDefinitionError ||
884- e instanceof MultipleDefinitionsError
885- ) {
886- ( this . test as any ) . _retries = (
887- this . test as any
888- ) . _currentRetry ;
873+ return runStepWithLogGroup ( {
874+ keyword : ensure (
875+ "keyword" in scenarioStep && scenarioStep . keyword ,
876+ "Expected to find a keyword in the scenario step" ,
877+ ) ,
878+ argument,
879+ text,
880+ fn : ( ) => {
881+ try {
882+ return registry . runStepDefinition (
883+ this ,
884+ text ,
885+ dryRun ,
886+ argument ,
887+ ) ;
888+ } catch ( e ) {
889+ if (
890+ e instanceof MissingDefinitionError ||
891+ e instanceof MultipleDefinitionsError
892+ ) {
893+ ( this . test as any ) . _retries = (
894+ this . test as any
895+ ) . _currentRetry ;
896+ }
897+
898+ if ( e instanceof MissingDefinitionError ) {
899+ let parameterType : "dataTable" | "docString" | null =
900+ null ;
901+
902+ if ( pickleStep . argument ?. dataTable ) {
903+ parameterType = "dataTable" ;
904+ } else if ( pickleStep . argument ?. docString ) {
905+ parameterType = "docString" ;
889906 }
907+
908+ const snippets = new CucumberExpressionGenerator (
909+ ( ) =>
910+ context . registry . parameterTypeRegistry
911+ . parameterTypes ,
912+ )
913+ . generateExpressions ( pickleStep . text )
914+ . map ( ( expression ) =>
915+ generateSnippet (
916+ expression ,
917+ ensure (
918+ pickleStep . type ,
919+ "Expected pickleStep to have a type" ,
920+ ) ,
921+ parameterType ,
922+ ) ,
923+ ) ;
924+
925+ return taskSuggestion ( {
926+ id : context . newId ( ) ,
927+ pickleStepId : pickleStep . id ,
928+ snippets : snippets . map ( ( code ) => {
929+ return {
930+ language : "javascript" ,
931+ code,
932+ } ;
933+ } ) ,
934+ } ) . then ( ( ) => {
935+ throw new Error (
936+ createMissingStepDefinitionMessage (
937+ context ,
938+ pickleStep ,
939+ snippets ,
940+ ) ,
941+ ) ;
942+ } ) ;
943+ } else {
890944 throw e ;
891945 }
892- } ,
893- } )
894- . then ( convertReturnValueToTestStepResultStatus )
895- . then ( ( status ) => {
896- const testStepResult = {
897- status,
898- duration : duration ( start , createTimestamp ( ) ) ,
899- } ;
900-
901- return {
902- beforeStepHookResults,
903- testStepResult,
904- } ;
905- } ) ;
906- } catch ( e ) {
907- if ( e instanceof MissingDefinitionError ) {
908- throw new Error (
909- createMissingStepDefinitionMessage (
910- context ,
911- pickleStep ,
912- context . registry . parameterTypeRegistry ,
913- ) ,
914- ) ;
915- } else {
916- throw e ;
917- }
918- }
946+ }
947+ } ,
948+ } )
949+ . then ( convertReturnValueToTestStepResultStatus )
950+ . then ( ( status ) => {
951+ const testStepResult = {
952+ status,
953+ duration : duration ( start , createTimestamp ( ) ) ,
954+ } ;
955+
956+ return {
957+ beforeStepHookResults,
958+ testStepResult,
959+ } ;
960+ } ) ;
919961 } )
920962 . then ( ( { beforeStepHookResults, testStepResult } ) => {
921963 return afterStepHooksChain ( ) . then ( ( afterStepHookResults ) => {
@@ -1574,7 +1616,7 @@ function strictIsTextTerminal(): boolean {
15741616function createMissingStepDefinitionMessage (
15751617 context : CompositionContext ,
15761618 pickleStep : messages . PickleStep ,
1577- parameterTypeRegistry : ParameterTypeRegistry ,
1619+ snippets : string [ ] ,
15781620) {
15791621 const noStepDefinitionPathsTemplate = `
15801622 Step implementation missing for "<text>".
@@ -1629,28 +1671,6 @@ function createMissingStepDefinitionMessage(
16291671 const prettyPrintList = ( items : string [ ] ) =>
16301672 items . map ( ( item ) => " - " + maybeEscape ( item ) ) . join ( "\n" ) ;
16311673
1632- let parameter : "dataTable" | "docString" | null = null ;
1633-
1634- if ( pickleStep . argument ?. dataTable ) {
1635- parameter = "dataTable" ;
1636- } else if ( pickleStep . argument ?. docString ) {
1637- parameter = "docString" ;
1638- }
1639-
1640- const snippets = new CucumberExpressionGenerator (
1641- ( ) => parameterTypeRegistry . parameterTypes ,
1642- )
1643- . generateExpressions ( pickleStep . text )
1644- . map ( ( expression ) =>
1645- generateSnippet (
1646- expression ,
1647- ensure ( pickleStep . type , "Expected pickleStep to have a type" ) ,
1648- parameter ,
1649- ) ,
1650- )
1651- . map ( ( snippet ) => indent ( snippet , { count : 2 } ) )
1652- . join ( "\n\n" ) ;
1653-
16541674 return stripIndent ( template )
16551675 . replaceAll ( "<text>" , pickleStep . text )
16561676 . replaceAll (
@@ -1665,7 +1685,10 @@ function createMissingStepDefinitionMessage(
16651685 "<step-definition-paths>" ,
16661686 prettyPrintList ( stepDefinitionHints . stepDefinitionPaths ) ,
16671687 )
1668- . replaceAll ( "<snippets>" , snippets ) ;
1688+ . replaceAll (
1689+ "<snippets>" ,
1690+ snippets . map ( ( snippet ) => indent ( snippet , { count : 2 } ) ) . join ( "\n\n" ) ,
1691+ ) ;
16691692}
16701693
16711694function mapArgumentGroup ( group : Group ) : messages . Group {
0 commit comments