@@ -32,134 +32,193 @@ import { notNull } from "./type-guards";
3232
3333import { getTags } from "./environment-helpers" ;
3434
35- export default async function addCucumberPreprocessorPlugin (
36- on : Cypress . PluginEvents ,
37- config : Cypress . PluginConfigOptions
38- ) {
39- const preprocessor = await resolve ( ) ;
35+ const preprocessorP = resolve ( ) ;
36+
37+ let currentTestStepStartedId : string ;
38+ let currentSpecMessages : messages . IEnvelope [ ] ;
39+
40+ export async function beforeRunHandler ( config : Cypress . PluginConfigOptions ) {
41+ const preprocessor = await preprocessorP ;
42+
43+ if ( ! preprocessor . messages . enabled ) {
44+ return ;
45+ }
4046
4147 const messagesPath = path . join (
4248 config . projectRoot ,
4349 preprocessor . messages . output
4450 ) ;
4551
46- const jsonPath = path . join ( config . projectRoot , preprocessor . json . output ) ;
52+ await fs . rm ( messagesPath , { force : true } ) ;
53+ }
4754
48- on ( "before:run" , async ( ) => {
49- if ( ! preprocessor . messages . enabled ) {
50- return ;
51- }
55+ export async function afterRunHandler ( config : Cypress . PluginConfigOptions ) {
56+ const preprocessor = await preprocessorP ;
5257
53- await fs . rm ( messagesPath , { force : true } ) ;
54- } ) ;
58+ if ( ! preprocessor . messages . enabled ) {
59+ return ;
60+ }
5561
56- on ( "after:run" , async ( ) => {
57- if ( ! preprocessor . messages . enabled ) {
58- return ;
59- }
62+ const messagesPath = path . join (
63+ config . projectRoot ,
64+ preprocessor . messages . output
65+ ) ;
6066
61- try {
62- await fs . access ( messagesPath , fsConstants . F_OK ) ;
63- } catch {
64- return ;
65- }
67+ const jsonPath = path . join ( config . projectRoot , preprocessor . json . output ) ;
6668
67- const messages = await fs . open ( messagesPath , "r" ) ;
69+ try {
70+ await fs . access ( messagesPath , fsConstants . F_OK ) ;
71+ } catch {
72+ return ;
73+ }
6874
69- try {
70- const json = await fs . open ( jsonPath , "w" ) ;
75+ const messages = await fs . open ( messagesPath , "r" ) ;
7176
72- try {
73- const child = child_process . spawn ( preprocessor . json . formatter , {
74- stdio : [ messages . fd , json . fd , "inherit" ] ,
75- } ) ;
77+ try {
78+ const json = await fs . open ( jsonPath , "w" ) ;
7679
77- await new Promise < void > ( ( resolve , reject ) => {
78- child . on ( "exit" , ( code ) => {
79- if ( code === 0 ) {
80- resolve ( ) ;
81- } else {
82- reject (
83- new Error (
84- `${ preprocessor . json . formatter } exited non-successfully`
85- )
86- ) ;
87- }
88- } ) ;
89-
90- child . on ( "error" , reject ) ;
80+ try {
81+ const child = child_process . spawn ( preprocessor . json . formatter , {
82+ stdio : [ messages . fd , json . fd , "inherit" ] ,
83+ } ) ;
84+
85+ await new Promise < void > ( ( resolve , reject ) => {
86+ child . on ( "exit" , ( code ) => {
87+ if ( code === 0 ) {
88+ resolve ( ) ;
89+ } else {
90+ reject (
91+ new Error (
92+ `${ preprocessor . json . formatter } exited non-successfully`
93+ )
94+ ) ;
95+ }
9196 } ) ;
92- } finally {
93- await json . close ( ) ;
94- }
97+
98+ child . on ( "error" , reject ) ;
99+ } ) ;
95100 } finally {
96- await messages . close ( ) ;
101+ await json . close ( ) ;
97102 }
98- } ) ;
103+ } finally {
104+ await messages . close ( ) ;
105+ }
106+ }
99107
100- let currentTestStepStartedId : string ;
101- let currentSpecMessages : messages . IEnvelope [ ] ;
108+ export async function beforeSpecHandler ( config : Cypress . PluginConfigOptions ) {
109+ currentSpecMessages = [ ] ;
110+ }
102111
103- on ( "before:spec" , ( ) => {
104- currentSpecMessages = [ ] ;
105- } ) ;
112+ export async function afterSpecHandler (
113+ config : Cypress . PluginConfigOptions ,
114+ spec : Cypress . Spec ,
115+ results : CypressCommandLine . RunResult
116+ ) {
117+ const preprocessor = await preprocessorP ;
106118
107- on ( "after:spec" , async ( _spec , results ) => {
108- // `results` is undefined when running via `cypress open`.
109- if ( ! preprocessor . messages . enabled || ! currentSpecMessages || ! results ) {
110- return ;
111- }
119+ const messagesPath = path . join (
120+ config . projectRoot ,
121+ preprocessor . messages . output
122+ ) ;
123+
124+ // `results` is undefined when running via `cypress open`.
125+ if ( ! preprocessor . messages . enabled || ! currentSpecMessages || ! results ) {
126+ return ;
127+ }
112128
113- const wasRemainingSkipped = results . tests . some ( ( test ) =>
114- test . displayError ?. match ( HOOK_FAILURE_EXPR )
129+ const wasRemainingSkipped = results . tests . some ( ( test ) =>
130+ test . displayError ?. match ( HOOK_FAILURE_EXPR )
131+ ) ;
132+
133+ if ( wasRemainingSkipped ) {
134+ console . log (
135+ chalk . yellow (
136+ ` Hook failures can't be represented in JSON reports, thus none is created for ${ spec . relative } .`
137+ )
115138 ) ;
139+ } else {
140+ await fs . writeFile (
141+ messagesPath ,
142+ currentSpecMessages . map ( ( message ) => JSON . stringify ( message ) ) . join ( "\n" ) +
143+ "\n" ,
144+ {
145+ flag : "a" ,
146+ }
147+ ) ;
148+ }
149+ }
116150
117- if ( wasRemainingSkipped ) {
118- console . log (
119- chalk . yellow (
120- ` Hook failures can't be represented in JSON reports, thus none is created for ${ _spec . relative } .`
121- )
122- ) ;
123- } else {
124- await fs . writeFile (
125- messagesPath ,
126- currentSpecMessages
127- . map ( ( message ) => JSON . stringify ( message ) )
128- . join ( "\n" ) + "\n" ,
129- {
130- flag : "a" ,
131- }
132- ) ;
133- }
134- } ) ;
151+ export async function afterScreenshotHandler (
152+ config : Cypress . PluginConfigOptions ,
153+ details : Cypress . ScreenshotDetails
154+ ) {
155+ const preprocessor = await preprocessorP ;
135156
136- on ( "after:screenshot" , async ( details ) => {
137- if ( ! preprocessor . messages . enabled || ! currentSpecMessages ) {
138- return details ;
139- }
157+ if ( ! preprocessor . messages . enabled || ! currentSpecMessages ) {
158+ return details ;
159+ }
140160
141- let buffer ;
161+ let buffer ;
142162
143- try {
144- buffer = await fs . readFile ( details . path ) ;
145- } catch {
146- return details ;
147- }
163+ try {
164+ buffer = await fs . readFile ( details . path ) ;
165+ } catch {
166+ return details ;
167+ }
148168
149- const message : messages . IEnvelope = {
150- attachment : {
151- testStepId : currentTestStepStartedId ,
152- body : buffer . toString ( "base64" ) ,
153- mediaType : "image/png" ,
154- contentEncoding :
155- "BASE64" as unknown as messages . Attachment . ContentEncoding ,
156- } ,
157- } ;
169+ const message : messages . IEnvelope = {
170+ attachment : {
171+ testStepId : currentTestStepStartedId ,
172+ body : buffer . toString ( "base64" ) ,
173+ mediaType : "image/png" ,
174+ contentEncoding :
175+ "BASE64" as unknown as messages . Attachment . ContentEncoding ,
176+ } ,
177+ } ;
158178
159- currentSpecMessages . push ( message ) ;
179+ currentSpecMessages . push ( message ) ;
160180
161- return details ;
162- } ) ;
181+ return details ;
182+ }
183+
184+ type AddOptions = {
185+ omitBeforeRunHandler ?: boolean ;
186+ omitAfterRunHandler ?: boolean ;
187+ omitBeforeSpecHandler ?: boolean ;
188+ omitAfterSpecHandler ?: boolean ;
189+ omitAfterScreenshotHandler ?: boolean ;
190+ } ;
191+
192+ export default async function addCucumberPreprocessorPlugin (
193+ on : Cypress . PluginEvents ,
194+ config : Cypress . PluginConfigOptions ,
195+ options : AddOptions = { }
196+ ) {
197+ const preprocessor = await preprocessorP ;
198+
199+ if ( ! options . omitBeforeRunHandler ) {
200+ on ( "before:run" , ( ) => beforeRunHandler ( config ) ) ;
201+ }
202+
203+ if ( ! options . omitAfterRunHandler ) {
204+ on ( "after:run" , ( ) => afterRunHandler ( config ) ) ;
205+ }
206+
207+ if ( ! options . omitBeforeSpecHandler ) {
208+ on ( "before:spec" , ( ) => beforeSpecHandler ( config ) ) ;
209+ }
210+
211+ if ( ! options . omitAfterSpecHandler ) {
212+ on ( "after:spec" , ( spec , results ) =>
213+ afterSpecHandler ( config , spec , results )
214+ ) ;
215+ }
216+
217+ if ( ! options . omitAfterScreenshotHandler ) {
218+ on ( "after:screenshot" , ( details ) =>
219+ afterScreenshotHandler ( config , details )
220+ ) ;
221+ }
163222
164223 on ( "task" , {
165224 [ TASK_APPEND_MESSAGES ] : ( messages : messages . IEnvelope [ ] ) => {
0 commit comments