Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions packages/cli/src/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@ import { loadChecklyConfig } from '../services/checkly-config-loader'
import { filterByFileNamePattern, filterByCheckNamePattern, filterByTags } from '../services/test-filters'
import type { Runtime } from '../rest/runtimes'
import { AuthCommand } from './authCommand'
import { BrowserCheck, Check, Diagnostics, HeartbeatCheck, MultiStepCheck, Project, RetryStrategyBuilder, Session } from '../constructs'
import {
BrowserCheck,
Check,
Diagnostics,
HeartbeatCheck,
MultiStepCheck,
PlaywrightCheck,
Project,
RetryStrategyBuilder,
Session
} from '../constructs'
import type { Region } from '..'
import { splitConfigFilePath, getGitInformation, getCiInformation, getEnvs } from '../services/util'
import { splitConfigFilePath, getGitInformation, getCiInformation, getEnvs, getPwtChecks } from '../services/util'
import { createReporters, ReporterType } from '../reporters/reporter'
import commonMessages from '../messages/common-messages'
import { TestResultsShortLinks } from '../rest/test-sessions'
Expand Down Expand Up @@ -112,6 +122,22 @@ export default class Test extends AuthCommand {
allowNo: true,
env: 'CHECKLY_VERIFY_RUNTIME_DEPENDENCIES',
}),
'pwTags': Flags.string({
description: 'A comma separated list of tags to filter Playwright tests by.' +
' Only Playwright tests wit at least one of the specified tags will be run.' +
' Multiple --pwtTags flags can be passed, in which case tests will be run if they match any of the --pwtTags filters.' +
' F.ex. `--pwTags production,webapp --pwTags production,backend` will run checks with tags (production AND webapp) OR (production AND backend).',
multiple: true,
required: false,
}),
'pwProjects': Flags.string({
description: 'A comma separated list of projects to filter Playwright tests by.' +
' Only Playwright tests in the specified projects will be run.' +
' Multiple --pwtProjects flags can be passed, in which case tests will be run if they match any of the --pwtProjects filters.' +
' If combining with --pwtTags, only tests that match both the specified projects and tags will be run.' ,
multiple: true,
required: false,
})
}

static args = {
Expand Down Expand Up @@ -146,6 +172,8 @@ export default class Test extends AuthCommand {
'update-snapshots': updateSnapshots,
retries,
'verify-runtime-dependencies': verifyRuntimeDependencies,
pwTags,
pwProjects
} = flags
const filePatterns = argv as string[]

Expand All @@ -164,6 +192,11 @@ export default class Test extends AuthCommand {
const { data: account } = await api.accounts.get(config.getAccountId())
const { data: availableRuntimes } = await api.runtimes.getAll()

const playwrightConfigPath = checklyConfig.checks?.playwrightConfigPath
const playwrightChecks = (pwProjects || pwTags)
? getPwtChecks(pwProjects, pwTags, playwrightConfigPath)
: checklyConfig.checks?.playwrightChecks

const project = await parseProject({
directory: configDirectory,
projectLogicalId: checklyConfig.logicalId,
Expand All @@ -183,14 +216,19 @@ export default class Test extends AuthCommand {
defaultRuntimeId: account.runtimeId,
verifyRuntimeDependencies,
checklyConfigConstructs,
playwrightConfigPath: checklyConfig.checks?.playwrightConfigPath,
playwrightConfigPath,
include: checklyConfig.checks?.include,
playwrightChecks: checklyConfig.checks?.playwrightChecks,
playwrightChecks,
checkFilter: check => {
if (check instanceof HeartbeatCheck) {
return false
}

if (pwProjects || pwTags) {
// if Playwright projects or tags are specified, we only want to run Playwright checks
return check instanceof PlaywrightCheck
}

let entrypointMatch = false
if (check instanceof BrowserCheck || check instanceof MultiStepCheck) {
// For historical reasons the path used for filtering has always
Expand Down
54 changes: 52 additions & 2 deletions packages/cli/src/services/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import archiver from 'archiver'
import type { Archiver } from 'archiver'
import { glob } from 'glob'
import os from 'node:os'
import { ChecklyConfig } from './checkly-config-loader'
import { ChecklyConfig, PlaywrightSlimmedProp } from './checkly-config-loader'
import { Parser } from './check-parser/parser'
import * as JSON5 from 'json5'
import { PlaywrightConfig } from './playwright-config'
import { access , readFile} from 'fs/promises'
import { createHash } from 'crypto';
import { Session } from '../constructs'
import { PlaywrightCheck, Session } from '../constructs'

export interface GitInformation {
commitId: string
Expand Down Expand Up @@ -321,3 +321,53 @@ export async function writeChecklyConfigFile (dir: string, config: ChecklyConfig

await fs.writeFile(configFile, configContent, { encoding: 'utf-8' })
}

export function getPwtChecks(pwProjects: string[] | undefined, pwTags: string[]| undefined, playwrightConfigPath: string | undefined): PlaywrightSlimmedProp[] {
if (!playwrightConfigPath) {
return []
}
let checks: PlaywrightSlimmedProp[] = []
// We are creating new checks on the fly, so we need to set the loading state.
if (!pwProjects && pwTags) {
checks = pwTags.map(tags => createPlaywrightChecks(undefined, tags, playwrightConfigPath))
} else if (pwProjects && !pwTags) {
checks = pwProjects.map(projects => createPlaywrightChecks(projects, '', playwrightConfigPath))
} else if (pwProjects && pwTags) {
const res = []
for (const project of pwProjects) {
for (const tag of pwTags) {
res.push(createPlaywrightChecks(project, tag, playwrightConfigPath))
}
}
checks = res
} else {
checks = []
}
return checks
}

function createPlaywrightChecks(projects: string | undefined, tags: string, playwrightConfigPath: string): PlaywrightSlimmedProp {
const logicalIdParts = []
const nameParts = []
if (projects) {
logicalIdParts.push(...projects)
nameParts.push(`Project: ${projects}`)
}
if (tags) {
logicalIdParts.push(tags)
nameParts.push(`Tags: ${tags}`)
}
const logicalId = `check-${logicalIdParts.map(part =>
part
.replace(' ', '-')
.replace(/[^a-zA-Z0-9]/g, '-')
.toLowerCase())
.join('-')}`
const name = `Playwright Check: ${nameParts.join(' - ')}`
return {
logicalId,
name,
pwProjects: projects ? projects.split(',') : [],
pwTags: tags ? tags.split(',').map(tag => tag.trim()) : [],
}
}
Loading