Skip to content

feat: added int and e2e tests to blank and website templates #12866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
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
9 changes: 9 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ jobs:
include:
- template: blank
database: mongodb
templateName: '@payloadcms/template-blank'
- template: website
database: mongodb
- template: with-payload-cloud
Expand Down Expand Up @@ -612,6 +613,14 @@ jobs:
env:
NODE_OPTIONS: --max-old-space-size=8096

- name: Runs Template Int Tests
run: pnpm --filter ${{ matrix.templateName }} run test:int
env:
NODE_OPTIONS: --max-old-space-size=8096
PAYLOAD_DATABASE: ${{ matrix.database }}
POSTGRES_URL: ${{ env.POSTGRES_URL }}
MONGODB_URL: mongodb://localhost:27017/payloadtests

tests-type-generation:
runs-on: ubuntu-24.04
needs: [changes, build]
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
"bf": "pnpm run build:force",
"build": "pnpm run build:core",
"build:admin-bar": "turbo build --filter \"@payloadcms/admin-bar\"",
"build:all": "turbo build",
"build:all": "turbo build --filter \"!@payloadcms/template-*\"",
"build:app": "next build",
"build:app:analyze": "cross-env ANALYZE=true next build",
"build:clean": "pnpm clean:build",
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\" --filter \"!@payloadcms/storage-*\"",
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\" --filter \"!@payloadcms/storage-*\" --filter \"!@payloadcms/template-*\"",
"build:core:force": "pnpm clean:build && pnpm build:core --no-cache --force",
"build:create-payload-app": "turbo build --filter create-payload-app",
"build:db-mongodb": "turbo build --filter \"@payloadcms/db-mongodb\"",
Expand Down Expand Up @@ -79,9 +79,9 @@
"docker:start": "docker compose -f test/docker-compose.yml up -d",
"docker:stop": "docker compose -f test/docker-compose.yml down",
"force:build": "pnpm run build:core:force",
"lint": "turbo run lint --log-order=grouped --continue",
"lint": "turbo run lint --log-order=grouped --continue --filter \"!@payloadcms/template-*\"",
"lint-staged": "lint-staged",
"lint:fix": "turbo run lint:fix --log-order=grouped --continue",
"lint:fix": "turbo run lint:fix --log-order=grouped --continue --filter \"!@payloadcms/template-*\"",
"obliterate-playwright-cache-macos": "rm -rf ~/Library/Caches/ms-playwright && find /System/Volumes/Data/private/var/folders -type d -name 'playwright*' -exec rm -rf {} +",
"prepare": "husky",
"prepare-run-test-against-prod": "pnpm bf && rm -rf test/packed && rm -rf test/node_modules && rm -rf app && rm -f test/pnpm-lock.yaml && pnpm run script:pack --all --no-build --dest test/packed && pnpm runts test/setupProd.ts && cd test && pnpm i --ignore-workspace && cd ..",
Expand Down Expand Up @@ -182,7 +182,7 @@
"tempy": "1.0.1",
"tstyche": "^3.1.1",
"tsx": "4.19.2",
"turbo": "^2.3.3",
"turbo": "^2.5.4",
"typescript": "5.7.3"
},
"packageManager": "[email protected]",
Expand Down
34 changes: 33 additions & 1 deletion packages/create-payload-app/src/lib/create-project.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import path from 'path'

import type { CliArgs, DbType, ProjectExample, ProjectTemplate } from '../types.js'

import { createProject } from './create-project.js'
import { createProject, updatePackageJSONDependencies } from './create-project.js'
import { dbReplacements } from './replacements.js'
import { getValidTemplates } from './templates.js'

Expand Down Expand Up @@ -179,5 +179,37 @@ describe('createProject', () => {
expect(content).toContain(dbReplacement.configReplacement().join('\n'))
})
})

describe('updates package.json', () => {
it('updates package name and bumps workspace versions', async () => {
const latestVersion = '3.0.0'
const initialJSON = {
name: 'test-project',
version: '1.0.0',
dependencies: {
'@payloadcms/db-mongodb': 'workspace:*',
payload: 'workspace:*',
'@payloadcms/ui': 'workspace:*',
},
}

const correctlyModifiedJSON = {
name: 'test-project',
version: '1.0.0',
dependencies: {
'@payloadcms/db-mongodb': `${latestVersion}`,
payload: `${latestVersion}`,
'@payloadcms/ui': `${latestVersion}`,
},
}

updatePackageJSONDependencies({
latestVersion,
packageJson: initialJSON,
})

expect(initialJSON).toEqual(correctlyModifiedJSON)
})
})
})
})
94 changes: 92 additions & 2 deletions packages/create-payload-app/src/lib/create-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ export async function createProject(
const spinner = p.spinner()
spinner.start('Checking latest Payload version...')

await updatePackageJSON({ projectDir, projectName })
const payloadVersion = await getLatestPackageVersion({ packageName: 'payload' })

spinner.stop(`Found latest version of Payload ${payloadVersion}`)

await updatePackageJSON({ latestVersion: payloadVersion, projectDir, projectName })

if ('template' in args) {
if (args.template.type === 'plugin') {
Expand Down Expand Up @@ -177,17 +181,103 @@ export async function createProject(
}
}

/**
* Reads the package.json file into an object and then does the following:
* - Sets the `name` property to the provided `projectName`.
* - Bumps the payload packages from workspace:* to the latest version.
* - Writes the updated object back to the package.json file.
*/
export async function updatePackageJSON(args: {
/**
* The latest version of Payload to use in the package.json.
*/
latestVersion: string
projectDir: string
/**
* The name of the project to set in package.json.
*/
projectName: string
}): Promise<void> {
const { projectDir, projectName } = args
const { latestVersion, projectDir, projectName } = args
const packageJsonPath = path.resolve(projectDir, 'package.json')
try {
const packageObj = await fse.readJson(packageJsonPath)
packageObj.name = projectName

updatePackageJSONDependencies({
latestVersion,
packageJson: packageObj,
})

await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })
} catch (err: unknown) {
warning(`Unable to update name in package.json. ${err instanceof Error ? err.message : ''}`)
}
}

/**
* Recursively updates a JSON object to replace all instances of `workspace:` with the latest version pinned.
*
* Does not return and instead modifies the `packageJson` object in place.
*/
export function updatePackageJSONDependencies(args: {
latestVersion: string
packageJson: Record<string, unknown>
}): void {
const { latestVersion, packageJson } = args

const updatedDependencies = Object.entries(packageJson.dependencies || {}).reduce(
(acc, [key, value]) => {
if (typeof value === 'string' && value.startsWith('workspace:')) {
acc[key] = `${latestVersion}`
} else {
acc[key] = value
}
return acc
},
{} as Record<string, string>,
)
packageJson.dependencies = updatedDependencies
}

/**
* Fetches the latest version of a package from the NPM registry.
*
* Used in determining the latest version of Payload to use in the generated templates.
*/
async function getLatestPackageVersion({
packageName = 'payload',
}: {
/**
* Package name to fetch the latest version for based on the NPM registry URL
*
* Eg. for `'payload'`, it will fetch the version from `https://registry.npmjs.org/payload`
*
* @default 'payload'
*/
packageName?: string
}): Promise<string> {
try {
const response = await fetch(`https://registry.npmjs.org/-/package/${packageName}/dist-tags`)
const data = await response.json()

// Monster chaining for type safety just checking for data['dist-tags'].latest
const latestVersion =
data &&
typeof data === 'object' &&
'latest' in data &&
data.latest &&
typeof data.latest === 'string'
? data.latest
: null

if (!latestVersion) {
throw new Error(`No latest version found for package: ${packageName}`)
}

return latestVersion
} catch (error) {
console.error('Error fetching Payload version:', error)
throw error
}
}
2 changes: 1 addition & 1 deletion packages/create-payload-app/src/lib/download-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function downloadTemplate({
}) {
const branchOrTag = template.url.split('#')?.[1] || 'latest'
const url = `https://codeload.github.com/payloadcms/payload/tar.gz/${branchOrTag}`
const filter = `payload-${branchOrTag.replace(/^v/, '')}/templates/${template.name}/`
const filter = `payload-${branchOrTag.replace(/^v/, '').replaceAll('/', '-')}/templates/${template.name}/`

if (debug) {
debugLog(`Using template url: ${template.url}`)
Expand Down
4 changes: 4 additions & 0 deletions packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
],
"type": "module",
"exports": {
"./css": {
"import": "./src/dummy.css",
"default": "./src/dummy.css"
},
".": {
"import": "./src/index.js",
"types": "./src/index.js",
Expand Down
Empty file added packages/next/src/dummy.css
Empty file.
Loading
Loading