@@ -32,6 +32,7 @@ import {
3232 findPropertyByName ,
3333 reWriteChecklyConfigFile ,
3434} from '../helpers/write-config-helpers'
35+ import * as acornParser from '../helpers/recast-acorn-parser'
3536import * as JSON5 from 'json5'
3637import { detectPackageManager } from '../services/check-parser/package-files/package-manager'
3738import { DEFAULT_REGION } from '../helpers/constants'
@@ -88,6 +89,12 @@ export default class PwTestCommand extends AuthCommand {
8889 description : 'Create a Checkly check from the Playwright test.' ,
8990 default : false ,
9091 } ) ,
92+ 'frequency' : Flags . integer ( {
93+ char : 'f' ,
94+ description : 'The frequency in minutes for the created check.' ,
95+ default : 10 ,
96+ options : [ '1' , '2' , '5' , '10' , '15' , '30' , '60' , '120' , '180' , '360' , '720' , '1440' ] ,
97+ } ) ,
9198 'stream-logs' : Flags . boolean ( {
9299 description : 'Stream logs from the test run to the console.' ,
93100 default : true ,
@@ -121,6 +128,7 @@ export default class PwTestCommand extends AuthCommand {
121128 'create-check' : createCheck ,
122129 'stream-logs' : streamLogs ,
123130 'include' : includeFlag ,
131+ 'frequency' : frequency ,
124132 } = flags
125133 const { configDirectory, configFilenames } = splitConfigFilePath ( configFilename )
126134 const pwPathFlag = this . getConfigPath ( playwrightFlags )
@@ -147,6 +155,7 @@ export default class PwTestCommand extends AuthCommand {
147155 runLocation as keyof Region ,
148156 privateRunLocation ,
149157 dir ,
158+ frequency ,
150159 )
151160 if ( createCheck ) {
152161 this . style . actionStart ( 'Adding check with specified options to the Checkly config file' )
@@ -245,7 +254,8 @@ export default class PwTestCommand extends AuthCommand {
245254 const checkBundles = Object . values ( projectBundle . data . check )
246255
247256 if ( ! checkBundles . length ) {
248- this . log ( `Unable to find checks to run` )
257+ this . style . shortError ( 'Unable to find checks to run.' )
258+ this . style . shortInfo ( 'Check your Playwright configuration to ensure it targets your test files.' )
249259 return
250260 }
251261
@@ -297,10 +307,15 @@ export default class PwTestCommand extends AuthCommand {
297307 } , links ) )
298308 } )
299309
310+ const noTestsFoundChecks = new Set < string > ( )
311+
300312 runner . on ( Events . CHECK_SUCCESSFUL ,
301313 ( sequenceId : SequenceId , check , result , testResultId , links ?: TestResultsShortLinks ) => {
302314 if ( result . hasFailures ) {
303315 process . exitCode = 1
316+ if ( noTestsFoundChecks . has ( check . logicalId ) ) {
317+ this . style . shortInfo ( 'Check your Playwright configuration to ensure it targets your test files.' )
318+ }
304319 }
305320
306321 reporters . forEach ( r => r . onCheckEnd ( sequenceId , {
@@ -318,6 +333,9 @@ export default class PwTestCommand extends AuthCommand {
318333 hasFailures : true ,
319334 runError : message ,
320335 } ) )
336+ if ( message . includes ( 'No tests found' ) ) {
337+ this . style . shortInfo ( 'Check your Playwright configuration to ensure it targets your test files.' )
338+ }
321339 process . exitCode = 1
322340 } )
323341 runner . on ( Events . RUN_FINISHED , ( ) => reporters . forEach ( r => r . onEnd ( ) ) )
@@ -327,6 +345,10 @@ export default class PwTestCommand extends AuthCommand {
327345 } )
328346 runner . on ( Events . STREAM_LOGS , ( check : any , sequenceId : SequenceId , logs ) => {
329347 reporters . forEach ( r => r . onStreamLogs ( check , sequenceId , logs ) )
348+ const hasNoTestsFound = logs . some ( ( log : { message : string } ) => log . message ?. includes ( 'No tests found' ) )
349+ if ( hasNoTestsFound ) {
350+ noTestsFoundChecks . add ( check . logicalId )
351+ }
330352 } )
331353 await runner . run ( )
332354 }
@@ -336,6 +358,7 @@ export default class PwTestCommand extends AuthCommand {
336358 runLocation : keyof Region ,
337359 privateRunLocation : string | undefined ,
338360 dir : string ,
361+ frequency : number = 10 ,
339362 ) : Promise < PlaywrightSlimmedProp > {
340363 const parseArgs = args . map ( arg => shellQuote ( arg ) )
341364 const input = parseArgs . join ( ' ' ) || ''
@@ -352,7 +375,7 @@ export default class PwTestCommand extends AuthCommand {
352375 name : `Playwright Test: ${ input } ` ,
353376 testCommand,
354377 ...locationConfig ,
355- frequency : 10 ,
378+ frequency,
356379 }
357380 }
358381
@@ -378,7 +401,7 @@ export default class PwTestCommand extends AuthCommand {
378401 this . style . actionSuccess ( )
379402 return
380403 }
381- const checklyAst = recast . parse ( configFile . checklyConfig )
404+ const checklyAst = recast . parse ( configFile . checklyConfig , { parser : acornParser } )
382405 const checksAst = findPropertyByName ( checklyAst , 'checks' )
383406 if ( ! checksAst ) {
384407 this . style . longError ( 'Unable to automatically sync your config file.' , 'This can happen if your Checkly config is '
@@ -395,7 +418,7 @@ export default class PwTestCommand extends AuthCommand {
395418 )
396419
397420 const playwrightCheckString = `const playwrightCheck = ${ JSON5 . stringify ( playwrightCheck , { space : 2 } ) } `
398- const playwrightCheckAst = recast . parse ( playwrightCheckString )
421+ const playwrightCheckAst = recast . parse ( playwrightCheckString , { parser : acornParser } )
399422 const playwrightCheckNode = playwrightCheckAst . program . body [ 0 ] . declarations [ 0 ] . init
400423 addOrReplaceItem ( checksAst . value , playwrightPropertyNode , 'playwrightConfigPath' )
401424 addItemToArray ( checksAst . value , playwrightCheckNode , 'playwrightChecks' )
0 commit comments