From d7a3d04e82d70c2ff9605222c5c799d386fe5473 Mon Sep 17 00:00:00 2001 From: Lynette Lopez Date: Tue, 10 Dec 2024 19:29:16 -0500 Subject: [PATCH] Add changeset Signed-off-by: Lynette Lopez Add new package.json templates to `templatePackagePaths` Signed-off-by: Lynette Lopez Copy over templates/default-app files Signed-off-by: Lynette Lopez Copy over templates/default-app/.yarn/* files Signed-off-by: Lynette Lopez Copy over templates/default-app/examples/* files Signed-off-by: Lynette Lopez Copy over templates/default-app/packages/backend/* files Signed-off-by: Lynette Lopez Copy over templates/default-app/packages files Signed-off-by: Lynette Lopez Copy over templates/default-app/plugins/* files Signed-off-by: Lynette Lopez Combine templates/default-app/app-config.yaml.hbs & packages/app-next/app-config.yaml Signed-off-by: Lynette Lopez Combine templates/default-app/packages/app/* & packages/app-next/* Signed-off-by: Lynette Lopez Align App.tsx with template's backend package Signed-off-by: Lynette Lopez Misc. changes that align templates/default-app & templates/default-app-next Signed-off-by: Lynette Lopez Add default-app-next's frontend packages to versions file and mocks Signed-off-by: Lynette Lopez Add `--experimental-frontend` CLI flag Signed-off-by: Lynette Lopez Fix default-app-next's frontend package name Signed-off-by: Lynette Lopez Fix spacing around `scripts` block Signed-off-by: Lynette Lopez PR review: Clarify changeset message Signed-off-by: Lynette Lopez PR review: Reduce to one default template with two frontend packages (1/2) Signed-off-by: Lynette Lopez PR review: Reduce to one default template with two frontend packages (2/2) Signed-off-by: Lynette Lopez PR review: Trim down packages/app-next Signed-off-by: Lynette Lopez Bug: Normalize Windows paths while parsing them out Signed-off-by: Lynette Lopez Update packages/create-app/templates/default-app/packages/app-next/README.md Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: Lynette Lopez Small follow up Signed-off-by: Andre Wanlin Fixed test Signed-off-by: Andre Wanlin --- .changeset/bright-elephants-sparkle.md | 5 + packages/create-app/README.md | 14 +++ packages/create-app/cli-report.md | 1 + packages/create-app/src/createApp.test.ts | 38 +++++-- packages/create-app/src/createApp.ts | 33 ++++-- packages/create-app/src/index.ts | 4 + packages/create-app/src/lib/tasks.test.ts | 74 ++++++++----- packages/create-app/src/lib/tasks.ts | 19 +++- packages/create-app/src/lib/versions.ts | 37 ++++--- .../packages/app-next/.eslintignore | 1 + .../packages/app-next/.eslintrc.js.hbs | 5 + .../default-app/packages/app-next/README.md | 9 ++ .../packages/app-next/e2e-tests/app.test.ts | 27 +++++ .../packages/app-next/package.json.hbs | 64 +++++++++++ .../public/android-chrome-192x192.png | Bin 0 -> 13599 bytes .../public/android-chrome-512x512.png | Bin 0 -> 40325 bytes .../app-next/public/apple-touch-icon.png | Bin 0 -> 12619 bytes .../app-next/public/favicon-16x16.png | Bin 0 -> 883 bytes .../app-next/public/favicon-32x32.png | Bin 0 -> 1686 bytes .../packages/app-next/public/favicon.ico | Bin 0 -> 15086 bytes .../packages/app-next/public/favicon.svg | 1 + .../packages/app-next/public/index.html | 100 ++++++++++++++++++ .../packages/app-next/public/manifest.json | 15 +++ .../packages/app-next/public/robots.txt | 2 + .../app-next/public/safari-pinned-tab.svg | 1 + .../packages/app-next/src/App.test.tsx | 51 +++++++++ .../default-app/packages/app-next/src/App.tsx | 67 ++++++++++++ .../packages/app-next/src/index.tsx | 22 ++++ .../packages/app-next/src/setupTests.ts | 21 ++++ packages/e2e-test/src/commands/run.ts | 1 + 30 files changed, 551 insertions(+), 61 deletions(-) create mode 100644 .changeset/bright-elephants-sparkle.md create mode 100644 packages/create-app/templates/default-app/packages/app-next/.eslintignore create mode 100644 packages/create-app/templates/default-app/packages/app-next/.eslintrc.js.hbs create mode 100644 packages/create-app/templates/default-app/packages/app-next/README.md create mode 100644 packages/create-app/templates/default-app/packages/app-next/e2e-tests/app.test.ts create mode 100644 packages/create-app/templates/default-app/packages/app-next/package.json.hbs create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/android-chrome-192x192.png create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/android-chrome-512x512.png create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/apple-touch-icon.png create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/favicon-16x16.png create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/favicon-32x32.png create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/favicon.ico create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/favicon.svg create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/index.html create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/manifest.json create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/robots.txt create mode 100644 packages/create-app/templates/default-app/packages/app-next/public/safari-pinned-tab.svg create mode 100644 packages/create-app/templates/default-app/packages/app-next/src/App.test.tsx create mode 100644 packages/create-app/templates/default-app/packages/app-next/src/App.tsx create mode 100644 packages/create-app/templates/default-app/packages/app-next/src/index.tsx create mode 100644 packages/create-app/templates/default-app/packages/app-next/src/setupTests.ts diff --git a/.changeset/bright-elephants-sparkle.md b/.changeset/bright-elephants-sparkle.md new file mode 100644 index 0000000000..05dc6150c6 --- /dev/null +++ b/.changeset/bright-elephants-sparkle.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Created a flag for scaffolding apps using the new frontend system. diff --git a/packages/create-app/README.md b/packages/create-app/README.md index d5b5039d4e..22e35fdc00 100644 --- a/packages/create-app/README.md +++ b/packages/create-app/README.md @@ -19,6 +19,20 @@ yarn install yarn backstage-create-app ``` +## Testing Changes Locally + +If you want to be able to test changes to `create-app` locally you can run the following command: + +```sh +./path/to/your/backstage/fork/backstage/packages/create-app/bin/backstage-create-app +``` + +If your fork lives in `~/repos/forks` then it would be: + +```sh +~/repos/forks/backstage/packages/create-app/bin/backstage-create-app +``` + ## Documentation - [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) diff --git a/packages/create-app/cli-report.md b/packages/create-app/cli-report.md index 982661fbf5..081371b0c0 100644 --- a/packages/create-app/cli-report.md +++ b/packages/create-app/cli-report.md @@ -8,6 +8,7 @@ Usage: backstage-create-app [options] Options: + --experimental-frontend --path [directory] --skip-install --template-path [directory] diff --git a/packages/create-app/src/createApp.test.ts b/packages/create-app/src/createApp.test.ts index 844d2aee1b..02fc068f95 100644 --- a/packages/create-app/src/createApp.test.ts +++ b/packages/create-app/src/createApp.test.ts @@ -57,7 +57,7 @@ describe('command entrypoint', () => { jest.resetAllMocks(); }); - test('should call expected tasks with no path option', async () => { + test('should call expected tasks with no `--path` option', async () => { const cmd = {} as unknown as Command; await createApp(cmd); expect(checkAppExistsMock).toHaveBeenCalled(); @@ -74,11 +74,12 @@ describe('command entrypoint', () => { expect(templatingMock.mock.lastCall?.[1]).toContain( path.join(tmpdir(), 'MyApp'), ); + expect(templatingMock.mock.lastCall?.[3]).toEqual(['packages/app-next/']); expect(moveAppMock).toHaveBeenCalled(); expect(buildAppMock).toHaveBeenCalled(); }); - it('should call expected tasks with path option', async () => { + it('should call expected tasks with `--path` option', async () => { const cmd = { path: 'myDirectory' } as unknown as Command; await createApp(cmd); expect(checkPathExistsMock).toHaveBeenCalled(); @@ -93,10 +94,33 @@ describe('command entrypoint', () => { ), ); expect(templatingMock.mock.lastCall?.[1]).toEqual('myDirectory'); + expect(templatingMock.mock.lastCall?.[3]).toEqual(['packages/app-next/']); expect(buildAppMock).toHaveBeenCalled(); }); - it('should call expected tasks with relative --template-path option', async () => { + it('should call expected tasks when `--experimental-frontend` is supplied', async () => { + const cmd = { experimentalFrontend: true } as unknown as Command; + await createApp(cmd); + expect(checkAppExistsMock).toHaveBeenCalled(); + expect(tryInitGitRepositoryMock).toHaveBeenCalled(); + expect(templatingMock).toHaveBeenCalled(); + expect(templatingMock.mock.lastCall?.[0]).toEqual( + findPaths(__dirname).resolveTarget( + 'packages', + 'create-app', + 'templates', + 'default-app', + ), + ); + expect(templatingMock.mock.lastCall?.[1]).toContain( + path.join(tmpdir(), 'MyApp'), + ); + expect(templatingMock.mock.lastCall?.[3]).toEqual(['packages/app/']); + expect(moveAppMock).toHaveBeenCalled(); + expect(buildAppMock).toHaveBeenCalled(); + }); + + it('should call expected tasks with relative `--template-path` option', async () => { const cmd = { path: 'myDirectory', templatePath: 'templateDirectory', @@ -109,10 +133,11 @@ describe('command entrypoint', () => { findPaths(__dirname).resolveTarget('templateDirectory'), ); expect(templatingMock.mock.lastCall?.[1]).toEqual('myDirectory'); + expect(templatingMock.mock.lastCall?.[3]).toEqual([]); expect(buildAppMock).toHaveBeenCalled(); }); - it('should call expected tasks with absolute --template-path option', async () => { + it('should call expected tasks with absolute `--template-path` option', async () => { const cmd = { path: 'myDirectory', templatePath: path.resolve('somewhere', 'templateDirectory'), @@ -125,16 +150,17 @@ describe('command entrypoint', () => { path.resolve('somewhere', 'templateDirectory'), ); expect(templatingMock.mock.lastCall?.[1]).toEqual('myDirectory'); + expect(templatingMock.mock.lastCall?.[3]).toEqual([]); expect(buildAppMock).toHaveBeenCalled(); }); - it('should not call `buildAppTask` when `skipInstall` is supplied', async () => { + it('should not call `buildAppTask()` when `--skip-install` is supplied', async () => { const cmd = { skipInstall: true } as unknown as Command; await createApp(cmd); expect(buildAppMock).not.toHaveBeenCalled(); }); - it('should not call `initGitRepository` when `gitConfig` is undefined', async () => { + it('should not call `initGitRepository()` when `gitConfig` is undefined', async () => { const cmd = {} as unknown as Command; readGitConfig.mockResolvedValue(undefined); await createApp(cmd); diff --git a/packages/create-app/src/createApp.ts b/packages/create-app/src/createApp.ts index d4d9dda18a..a2080bd45e 100644 --- a/packages/create-app/src/createApp.ts +++ b/packages/create-app/src/createApp.ts @@ -65,10 +65,17 @@ export default async (opts: OptionValues): Promise => { }, ]); + // Use `--template-path` argument as template when specified. Otherwise, use the default template. const templateDir = opts.templatePath ? paths.resolveTarget(opts.templatePath) : paths.resolveOwn('templates/default-app'); + // If using the default template, filter out `packages/app` when the `--experimental-frontend` flag + // is used or `packages/app-next` when its not used. + const excludedDirs = !opts.templatePath + ? [opts.experimentalFrontend ? 'packages/app/' : 'packages/app-next/'] + : []; + // Use `--path` argument as application directory when specified, otherwise // create a directory using `answers.name` const appDir = opts.path @@ -88,10 +95,15 @@ export default async (opts: OptionValues): Promise => { await checkPathExistsTask(appDir); Task.section('Preparing files'); - await templatingTask(templateDir, opts.path, { - ...answers, - defaultBranch: gitConfig?.defaultBranch ?? DEFAULT_BRANCH, - }); + await templatingTask( + templateDir, + opts.path, + { + ...answers, + defaultBranch: gitConfig?.defaultBranch ?? DEFAULT_BRANCH, + }, + excludedDirs, + ); } else { // Template to temporary location, and then move files @@ -102,10 +114,15 @@ export default async (opts: OptionValues): Promise => { const tempDir = await fs.mkdtemp(resolvePath(os.tmpdir(), answers.name)); Task.section('Preparing files'); - await templatingTask(templateDir, tempDir, { - ...answers, - defaultBranch: gitConfig?.defaultBranch ?? DEFAULT_BRANCH, - }); + await templatingTask( + templateDir, + tempDir, + { + ...answers, + defaultBranch: gitConfig?.defaultBranch ?? DEFAULT_BRANCH, + }, + excludedDirs, + ); Task.section('Moving to final location'); await moveAppTask(tempDir, appDir, answers.name); diff --git a/packages/create-app/src/index.ts b/packages/create-app/src/index.ts index d9b1226848..46e9f188e4 100644 --- a/packages/create-app/src/index.ts +++ b/packages/create-app/src/index.ts @@ -31,6 +31,10 @@ const main = (argv: string[]) => { .name('backstage-create-app') .version(version) .description('Creates a new app in a new directory or specified path') + .option( + '--experimental-frontend', + 'Use the default template with the experimental frontend', + ) .option( '--path [directory]', 'Location to store the app defaulting to a new folder with the app name', diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index c5d5092410..47735900ec 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -49,59 +49,65 @@ jest.mock('child_process'); jest.mock('./versions', () => ({ packageVersions: { root: '1.2.3', - '@backstage/cli': '1.0.0', + '@backstage/app-defaults': '1.0.0', '@backstage/backend-defaults': '1.0.0', '@backstage/backend-tasks': '1.0.0', + '@backstage/canon': '1.0.0', '@backstage/catalog-model': '1.0.0', '@backstage/catalog-client': '1.0.0', + '@backstage/catalog-model': '1.0.0', + '@backstage/cli': '1.0.0', '@backstage/config': '1.0.0', + '@backstage/core-app-api': '1.0.0', + '@backstage/core-components': '1.0.0', + '@backstage/core-plugin-api': '1.0.0', + '@backstage/e2e-test-utils': '1.0.0', + '@backstage/frontend-defaults': '1.0.0', + '@backstage/frontend-plugin-api': '1.0.0', + '@backstage/integration-react': '1.0.0', + '@backstage/plugin-api-docs': '1.0.0', '@backstage/plugin-app-backend': '1.0.0', + '@backstage/plugin-app-visualizer': '1.0.0', '@backstage/plugin-auth-backend': '1.0.0', - '@backstage/plugin-auth-node': '1.0.0', '@backstage/plugin-auth-backend-module-github-provider': '1.0.0', '@backstage/plugin-auth-backend-module-guest-provider': '1.0.0', + '@backstage/plugin-auth-node': '1.0.0', + '@backstage/plugin-catalog': '1.0.0', '@backstage/plugin-catalog-backend': '1.0.0', '@backstage/plugin-catalog-backend-module-logs': '1.0.0', '@backstage/plugin-catalog-backend-module-scaffolder-entity-model': '1.0.0', - '@backstage/plugin-permission-common': '1.0.0', - '@backstage/plugin-permission-node': '1.0.0', + '@backstage/plugin-catalog-common': '1.0.0', + '@backstage/plugin-catalog-graph': '1.0.0', + '@backstage/plugin-catalog-import': '1.0.0', + '@backstage/plugin-catalog-react': '1.0.0', + '@backstage/plugin-home': '1.0.0', + '@backstage/plugin-kubernetes': '1.0.0', + '@backstage/plugin-kubernetes-backend': '1.0.0', + '@backstage/plugin-org': '1.0.0', '@backstage/plugin-permission-backend': '1.0.0', '@backstage/plugin-permission-backend-module-allow-all-policy': '1.0.0', + '@backstage/plugin-permission-common': '1.0.0', + '@backstage/plugin-permission-node': '1.0.0', + '@backstage/plugin-permission-react': '1.0.0', '@backstage/plugin-proxy-backend': '1.0.0', + '@backstage/plugin-scaffolder': '1.0.0', '@backstage/plugin-scaffolder-backend': '1.0.0', + '@backstage/plugin-scaffolder-backend-module-github': '1.0.0', + '@backstage/plugin-search': '1.0.0', '@backstage/plugin-search-backend': '1.0.0', '@backstage/plugin-search-backend-module-catalog': '1.0.0', '@backstage/plugin-search-backend-module-pg': '1.0.0', '@backstage/plugin-search-backend-module-techdocs': '1.0.0', '@backstage/plugin-search-backend-node': '1.0.0', - '@backstage/plugin-techdocs-backend': '1.0.0', - '@backstage/app-defaults': '1.0.0', - '@backstage/core-app-api': '1.0.0', - '@backstage/core-components': '1.0.0', - '@backstage/core-plugin-api': '1.0.0', - '@backstage/e2e-test-utils': '1.0.0', - '@backstage/integration-react': '1.0.0', - '@backstage/plugin-api-docs': '1.0.0', - '@backstage/plugin-catalog': '1.0.0', - '@backstage/plugin-catalog-common': '1.0.0', - '@backstage/plugin-catalog-graph': '1.0.0', - '@backstage/plugin-catalog-import': '1.0.0', - '@backstage/plugin-catalog-react': '1.0.0', - '@backstage/plugin-kubernetes': '1.0.0', - '@backstage/plugin-kubernetes-backend': '1.0.0', - '@backstage/plugin-org': '1.0.0', - '@backstage/plugin-scaffolder': '1.0.0', - '@backstage/plugin-scaffolder-backend-module-github': '1.0.0', - '@backstage/plugin-permission-react': '1.0.0', - '@backstage/plugin-search': '1.0.0', '@backstage/plugin-search-react': '1.0.0', '@backstage/plugin-techdocs': '1.0.0', - '@backstage/plugin-techdocs-react': '1.0.0', + '@backstage/plugin-techdocs-backend': '1.0.0', '@backstage/plugin-techdocs-module-addons-contrib': '1.0.0', + '@backstage/plugin-techdocs-react': '1.0.0', '@backstage/plugin-user-settings': '1.0.0', - '@backstage/theme': '1.0.0', '@backstage/test-utils': '1.0.0', '@backstage/ui': '1.0.0', + '@backstage/theme': '1.0.0', }, })); @@ -267,7 +273,7 @@ describe('tasks', () => { }); describe('templatingTask', () => { - it('should generate a project populating context parameters', async () => { + it('should generate a project and populate context parameters', async () => { const templateDir = resolvePath(__dirname, '../../templates/default-app'); const destinationDir = 'templatedApp'; const context = { @@ -291,6 +297,20 @@ describe('tasks', () => { fs.readFile('templatedApp/packages/backend/package.json', 'utf-8'), ).resolves.toContain('sqlite3"'); }); + + it('should generate a project and skip excluded directories', async () => { + const templateDir = resolvePath(__dirname, '../../templates/default-app'); + const destinationDir = 'templatedApp'; + const context = { name: 'Backstage', dbTypeSqlite: true }; + const excludedDirs = ['packages/app-next']; + await templatingTask(templateDir, destinationDir, context, excludedDirs); + expect(fs.existsSync('templatedApp/packages/app/package.json')).toBe( + true, + ); + expect(fs.existsSync('templatedApp/packages/app-next/package.json')).toBe( + false, + ); + }); }); describe('readGitConfig', () => { diff --git a/packages/create-app/src/lib/tasks.ts b/packages/create-app/src/lib/tasks.ts index 51308275a6..197652e4c9 100644 --- a/packages/create-app/src/lib/tasks.ts +++ b/packages/create-app/src/lib/tasks.ts @@ -85,21 +85,32 @@ export class Task { * @param templateDir - location containing template files * @param destinationDir - location to save templated project * @param context - template parameters + * @param excludedDirs - template files to exclude */ export async function templatingTask( templateDir: string, destinationDir: string, context: any, + excludedDirs?: string[], ) { const files = await recursive(templateDir).catch(error => { throw new Error(`Failed to read template directory: ${error.message}`); }); for (const file of files) { - const destinationFile = resolvePath( - destinationDir, - relativePath(templateDir, file), - ); + const filePath = relativePath(templateDir, file); + + if ( + excludedDirs?.some(excludedDir => { + const normalizedFilePath = filePath.replace(/\\/g, '/'); + const normalizedExcludedDir = excludedDir.replace(/\\/g, '/'); + return normalizedFilePath.startsWith(normalizedExcludedDir); + }) + ) { + continue; + } + + const destinationFile = resolvePath(destinationDir, filePath); await fs.ensureDir(dirname(destinationFile)); if (file.endsWith('.hbs')) { diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index 179506063b..7211f992c6 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -33,6 +33,7 @@ import { version as root } from '../../../../package.json'; import { version as appDefaults } from '../../../app-defaults/package.json'; import { version as backendDefaults } from '../../../backend-defaults/package.json'; +import { version as canon } from '../../../canon/package.json'; import { version as catalogClient } from '../../../catalog-client/package.json'; import { version as catalogModel } from '../../../catalog-model/package.json'; import { version as cli } from '../../../cli/package.json'; @@ -41,56 +42,58 @@ import { version as coreAppApi } from '../../../core-app-api/package.json'; import { version as coreComponents } from '../../../core-components/package.json'; import { version as corePluginApi } from '../../../core-plugin-api/package.json'; import { version as e2eTestUtils } from '../../../e2e-test-utils/package.json'; -import { version as errors } from '../../../errors/package.json'; +import { version as frontendDefaults } from '../../../frontend-defaults/package.json'; +import { version as frontendPluginApi } from '../../../frontend-plugin-api/package.json'; import { version as integrationReact } from '../../../integration-react/package.json'; import { version as testUtils } from '../../../test-utils/package.json'; import { version as theme } from '../../../theme/package.json'; -import { version as repoTools } from '../../../repo-tools/package.json'; import { version as ui } from '../../../ui/package.json'; - import { version as pluginApiDocs } from '../../../../plugins/api-docs/package.json'; import { version as pluginAppBackend } from '../../../../plugins/app-backend/package.json'; +import { version as pluginAppVisualizer } from '../../../../plugins/app-visualizer/package.json'; import { version as pluginAuthBackend } from '../../../../plugins/auth-backend/package.json'; import { version as pluginAuthBackendModuleGithubProvider } from '../../../../plugins/auth-backend-module-github-provider/package.json'; import { version as pluginAuthBackendModuleGuestProvider } from '../../../../plugins/auth-backend-module-guest-provider/package.json'; import { version as pluginAuthNode } from '../../../../plugins/auth-node/package.json'; import { version as pluginCatalog } from '../../../../plugins/catalog/package.json'; -import { version as pluginCatalogCommon } from '../../../../plugins/catalog-common/package.json'; -import { version as pluginCatalogReact } from '../../../../plugins/catalog-react/package.json'; import { version as pluginCatalogBackend } from '../../../../plugins/catalog-backend/package.json'; import { version as pluginCatalogBackendModuleLogs } from '../../../../plugins/catalog-backend-module-logs/package.json'; import { version as pluginCatalogBackendModuleScaffolderEntityModel } from '../../../../plugins/catalog-backend-module-scaffolder-entity-model/package.json'; +import { version as pluginCatalogCommon } from '../../../../plugins/catalog-common/package.json'; import { version as pluginCatalogGraph } from '../../../../plugins/catalog-graph/package.json'; import { version as pluginCatalogImport } from '../../../../plugins/catalog-import/package.json'; +import { version as pluginCatalogReact } from '../../../../plugins/catalog-react/package.json'; +import { version as pluginHome } from '../../../../plugins/home/package.json'; import { version as pluginKubernetes } from '../../../../plugins/kubernetes/package.json'; import { version as pluginKubernetesBackend } from '../../../../plugins/kubernetes-backend/package.json'; import { version as pluginOrg } from '../../../../plugins/org/package.json'; import { version as pluginPermissionBackend } from '../../../../plugins/permission-backend/package.json'; import { version as pluginPermissionBackendModulePolicyAllowAll } from '../../../../plugins/permission-backend-module-policy-allow-all/package.json'; import { version as pluginPermissionCommon } from '../../../../plugins/permission-common/package.json'; -import { version as pluginPermissionReact } from '../../../../plugins/permission-react/package.json'; import { version as pluginPermissionNode } from '../../../../plugins/permission-node/package.json'; +import { version as pluginPermissionReact } from '../../../../plugins/permission-react/package.json'; import { version as pluginProxyBackend } from '../../../../plugins/proxy-backend/package.json'; import { version as pluginScaffolder } from '../../../../plugins/scaffolder/package.json'; import { version as pluginScaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json'; import { version as pluginScaffolderBackendModuleGithub } from '../../../../plugins/scaffolder-backend-module-github/package.json'; import { version as pluginSearch } from '../../../../plugins/search/package.json'; -import { version as pluginSearchReact } from '../../../../plugins/search-react/package.json'; import { version as pluginSearchBackend } from '../../../../plugins/search-backend/package.json'; import { version as pluginSearchBackendModuleCatalog } from '../../../../plugins/search-backend-module-catalog/package.json'; import { version as pluginSearchBackendModulePg } from '../../../../plugins/search-backend-module-pg/package.json'; import { version as pluginSearchBackendModuleTechdocs } from '../../../../plugins/search-backend-module-techdocs/package.json'; import { version as pluginSearchBackendNode } from '../../../../plugins/search-backend-node/package.json'; +import { version as pluginSearchReact } from '../../../../plugins/search-react/package.json'; import { version as pluginTechdocs } from '../../../../plugins/techdocs/package.json'; -import { version as pluginTechdocsReact } from '../../../../plugins/techdocs-react/package.json'; -import { version as pluginTechdocsModuleAddonsContrib } from '../../../../plugins/techdocs-module-addons-contrib/package.json'; import { version as pluginTechdocsBackend } from '../../../../plugins/techdocs-backend/package.json'; +import { version as pluginTechdocsModuleAddonsContrib } from '../../../../plugins/techdocs-module-addons-contrib/package.json'; +import { version as pluginTechdocsReact } from '../../../../plugins/techdocs-react/package.json'; import { version as pluginUserSettings } from '../../../../plugins/user-settings/package.json'; export const packageVersions = { root, '@backstage/app-defaults': appDefaults, '@backstage/backend-defaults': backendDefaults, + '@backstage/canon': canon, '@backstage/catalog-client': catalogClient, '@backstage/catalog-model': catalogModel, '@backstage/cli': cli, @@ -99,11 +102,12 @@ export const packageVersions = { '@backstage/core-components': coreComponents, '@backstage/core-plugin-api': corePluginApi, '@backstage/e2e-test-utils': e2eTestUtils, - '@backstage/errors': errors, + '@backstage/frontend-defaults': frontendDefaults, + '@backstage/frontend-plugin-api': frontendPluginApi, '@backstage/integration-react': integrationReact, - '@backstage/repo-tools': repoTools, '@backstage/plugin-api-docs': pluginApiDocs, '@backstage/plugin-app-backend': pluginAppBackend, + '@backstage/plugin-app-visualizer': pluginAppVisualizer, '@backstage/plugin-auth-backend': pluginAuthBackend, '@backstage/plugin-auth-backend-module-github-provider': pluginAuthBackendModuleGithubProvider, @@ -111,15 +115,16 @@ export const packageVersions = { pluginAuthBackendModuleGuestProvider, '@backstage/plugin-auth-node': pluginAuthNode, '@backstage/plugin-catalog': pluginCatalog, - '@backstage/plugin-catalog-common': pluginCatalogCommon, - '@backstage/plugin-catalog-react': pluginCatalogReact, '@backstage/plugin-catalog-backend': pluginCatalogBackend, '@backstage/plugin-catalog-backend-module-logs': pluginCatalogBackendModuleLogs, '@backstage/plugin-catalog-backend-module-scaffolder-entity-model': pluginCatalogBackendModuleScaffolderEntityModel, + '@backstage/plugin-catalog-common': pluginCatalogCommon, '@backstage/plugin-catalog-graph': pluginCatalogGraph, '@backstage/plugin-catalog-import': pluginCatalogImport, + '@backstage/plugin-catalog-react': pluginCatalogReact, + '@backstage/plugin-home': pluginHome, '@backstage/plugin-kubernetes': pluginKubernetes, '@backstage/plugin-kubernetes-backend': pluginKubernetesBackend, '@backstage/plugin-org': pluginOrg, @@ -135,7 +140,6 @@ export const packageVersions = { '@backstage/plugin-scaffolder-backend-module-github': pluginScaffolderBackendModuleGithub, '@backstage/plugin-search': pluginSearch, - '@backstage/plugin-search-react': pluginSearchReact, '@backstage/plugin-search-backend': pluginSearchBackend, '@backstage/plugin-search-backend-module-catalog': pluginSearchBackendModuleCatalog, @@ -143,11 +147,12 @@ export const packageVersions = { '@backstage/plugin-search-backend-module-techdocs': pluginSearchBackendModuleTechdocs, '@backstage/plugin-search-backend-node': pluginSearchBackendNode, + '@backstage/plugin-search-react': pluginSearchReact, '@backstage/plugin-techdocs': pluginTechdocs, - '@backstage/plugin-techdocs-react': pluginTechdocsReact, + '@backstage/plugin-techdocs-backend': pluginTechdocsBackend, '@backstage/plugin-techdocs-module-addons-contrib': pluginTechdocsModuleAddonsContrib, - '@backstage/plugin-techdocs-backend': pluginTechdocsBackend, + '@backstage/plugin-techdocs-react': pluginTechdocsReact, '@backstage/plugin-user-settings': pluginUserSettings, '@backstage/test-utils': testUtils, '@backstage/theme': theme, diff --git a/packages/create-app/templates/default-app/packages/app-next/.eslintignore b/packages/create-app/templates/default-app/packages/app-next/.eslintignore new file mode 100644 index 0000000000..a48cf0de7a --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/.eslintignore @@ -0,0 +1 @@ +public diff --git a/packages/create-app/templates/default-app/packages/app-next/.eslintrc.js.hbs b/packages/create-app/templates/default-app/packages/app-next/.eslintrc.js.hbs new file mode 100644 index 0000000000..e487f765b2 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/.eslintrc.js.hbs @@ -0,0 +1,5 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/create-app/templates/default-app/packages/app-next/README.md b/packages/create-app/templates/default-app/packages/app-next/README.md new file mode 100644 index 0000000000..5bd1f2cb92 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/README.md @@ -0,0 +1,9 @@ +# example-app + +This package is an example of a Backstage application using +the [New Frontend System](https://backstage.io/docs/frontend-system/). + +To play with it, open a terminal and run the command: `yarn start` + +**NOTE:** Don't forget to open a second terminal and to launch the backend there, using `yarn start`! The frontend +requires a backend to connect to. diff --git a/packages/create-app/templates/default-app/packages/app-next/e2e-tests/app.test.ts b/packages/create-app/templates/default-app/packages/app-next/e2e-tests/app.test.ts new file mode 100644 index 0000000000..839ff883de --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/e2e-tests/app.test.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { test, expect } from '@playwright/test'; + +test('App should render the welcome page', async ({ page }) => { + await page.goto('/'); + + const enterButton = page.getByRole('button', { name: 'Enter' }); + await expect(enterButton).toBeVisible(); + await enterButton.click(); + + await expect(page.getByText('My Company Catalog')).toBeVisible(); +}); diff --git a/packages/create-app/templates/default-app/packages/app-next/package.json.hbs b/packages/create-app/templates/default-app/packages/app-next/package.json.hbs new file mode 100644 index 0000000000..d94961ff1b --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/package.json.hbs @@ -0,0 +1,64 @@ +{ + "name": "app", + "version": "0.0.0", + "private": true, + "bundled": true, + "backstage": { + "role": "frontend" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "test": "backstage-cli package test", + "lint": "backstage-cli package lint" + }, + "dependencies": { + "@backstage/canon": "^{{version '@backstage/canon'}}", + "@backstage/cli": "^{{version '@backstage/cli'}}", + "@backstage/frontend-defaults": "^{{version '@backstage/frontend-defaults'}}", + "@backstage/frontend-plugin-api": "^{{version '@backstage/frontend-plugin-api'}}", + "@backstage/plugin-api-docs": "^{{version '@backstage/plugin-api-docs'}}", + "@backstage/plugin-app-visualizer": "^{{version '@backstage/plugin-app-visualizer'}}", + "@backstage/plugin-catalog": "^{{version '@backstage/plugin-catalog'}}", + "@backstage/plugin-catalog-graph": "^{{version '@backstage/plugin-catalog-graph'}}", + "@backstage/plugin-catalog-import": "^{{version '@backstage/plugin-catalog-import'}}", + "@backstage/plugin-home": "^{{version '@backstage/plugin-home'}}", + "@backstage/plugin-kubernetes": "^{{version '@backstage/plugin-kubernetes'}}", + "@backstage/plugin-org": "^{{version '@backstage/plugin-org'}}", + "@backstage/plugin-scaffolder": "^{{version '@backstage/plugin-scaffolder'}}", + "@backstage/plugin-search": "^{{version '@backstage/plugin-search'}}", + "@backstage/plugin-techdocs": "^{{version '@backstage/plugin-techdocs'}}", + "@backstage/plugin-techdocs-module-addons-contrib": "^{{version '@backstage/plugin-techdocs-module-addons-contrib'}}", + "@backstage/plugin-user-settings": "^{{version '@backstage/plugin-user-settings'}}", + "@backstage/theme": "^{{version '@backstage/theme'}}", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router": "^6.3.0", + "react-router-dom": "^6.3.0" + }, + "devDependencies": { + "@backstage/test-utils": "^{{version '@backstage/test-utils'}}", + "@playwright/test": "^1.32.3", + "@testing-library/jest-dom": "^6.0.0", + "@types/react": "*", + "@types/react-dom": "*" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "files": [ + "dist" + ] +} diff --git a/packages/create-app/templates/default-app/packages/app-next/public/android-chrome-192x192.png b/packages/create-app/templates/default-app/packages/app-next/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..eec0ae25b971cae8eb0033c9af7e0f676d1df663 GIT binary patch literal 13599 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 EANz~b2mk;8 literal 0 HcmV?d00001 diff --git a/packages/create-app/templates/default-app/packages/app-next/public/android-chrome-512x512.png b/packages/create-app/templates/default-app/packages/app-next/public/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..ac0578133bd74d60504d165216e9d4f6ba2fbfff GIT binary patch literal 40325 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

5PqA0)3L-3@%qNim8AQI->nx5 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 literal 0 HcmV?d00001 diff --git a/packages/create-app/templates/default-app/packages/app-next/public/apple-touch-icon.png b/packages/create-app/templates/default-app/packages/app-next/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6a45afb38f08b3dcd46d250bf544c328688363b8 GIT binary patch literal 12619 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 VSn|oqbSlsa22WQ%mvv4FO#qym7y1AI literal 0 HcmV?d00001 diff --git a/packages/create-app/templates/default-app/packages/app-next/public/favicon-32x32.png b/packages/create-app/templates/default-app/packages/app-next/public/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..c0915ece75949f3d917134f55193949927edc633 GIT binary patch literal 1686 zcmd5*YdF&j82@WYD9ojqT$Wo{SSXitp^eRqxy{@++t}P`atlKxQX0)YMm6_KR%p4F z$}J+6LMeH2OXWDHjylI#AJ2#L{k+fbeSgn;`91HK_szmP+3%H7kpcicc}5$z1N!Px-7om}akWbt233fdJ10ExN)z&Z~ATcQ$c2>@ad0I)&=0IMPZ zfJBuET&w|L$8)@+J4!Sl|Nk(stgJlvmnlJ&;dZvl8tO{Q%IJ*5_~q$1+xa={mdc0(T`t!w?RZl>^IxA*%bGu3bF$<*nzTrF> zoQ&9oiO|s=ORAp|1maSVle9kTR(cJ300u{&4iq#dewwjMjZ;umbia|8`fV}#)u6uZ z2{{=Vn6Y8_#3SbXb1ic-&s#nMteerJ5NT@9WJFf_0Z{rXvToRrSOV|5nT6}g)=)7clCVKtHJ1*VPs-V;@XTM)*hF8A>dvO zHk*Y?X8JaA;})mFp7;7TRRuk~8$R*Snh{9txf3X8a4%y!TuP;MHGAGHB;T*cTs()( zPBU^uyOrcpI-AkwlQc~ccBy9xRRz@U7IH^D@piFSO__BF#e(AN-^z2yOmV!NrfGJV z)K=@)T;PiA16X29aqmP@px{GT+&pJ*OCU>i#GE8dw3RuCdu^ zY|d<%y|L(_@zJ9#_m z=Lc$*iilj{bjSDeNH|lRP>yLE)Yq?l!XVsP?uHhR(xnf>5p}vuAuF-j7*tA0oTAH zhFP&ZPMN7z8!K6i|K8u7|AYJvRll0p!ov{KSr|$njU-`o&7fVZN5@WQ|g`Mlirnap=oY~b#iCdHeScp|7sct zd}FL!1NSuuCnVle?ygaP975V!)pzN#*|A{{1* z$fS~)G%HFBO+IIv4>f5HNGY_6SF`0>Gf0kWIFv^nU=X CgrE5U literal 0 HcmV?d00001 diff --git a/packages/create-app/templates/default-app/packages/app-next/public/favicon.ico b/packages/create-app/templates/default-app/packages/app-next/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5e45e5dfbde6f39603d5be60d933c1af14dffb1e GIT binary patch literal 15086 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 D+pS%} literal 0 HcmV?d00001 diff --git a/packages/create-app/templates/default-app/packages/app-next/public/favicon.svg b/packages/create-app/templates/default-app/packages/app-next/public/favicon.svg new file mode 100644 index 0000000000..7f2d375cd8 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/public/favicon.svg @@ -0,0 +1 @@ +Backstage favicon \ No newline at end of file diff --git a/packages/create-app/templates/default-app/packages/app-next/public/index.html b/packages/create-app/templates/default-app/packages/app-next/public/index.html new file mode 100644 index 0000000000..63ab0bec0c --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/public/index.html @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + <%= config.getString('app.title') %> + + <% if (config.has('app.datadogRum')) { %> + + <% } %> + + + + +

+ + + diff --git a/packages/create-app/templates/default-app/packages/app-next/public/manifest.json b/packages/create-app/templates/default-app/packages/app-next/public/manifest.json new file mode 100644 index 0000000000..4a7c1b4ec4 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "Backstage", + "name": "Backstage", + "icons": [ + { + "src": "favicon.ico", + "sizes": "48x48", + "type": "image/png" + } + ], + "start_url": "./index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/packages/create-app/templates/default-app/packages/app-next/public/robots.txt b/packages/create-app/templates/default-app/packages/app-next/public/robots.txt new file mode 100644 index 0000000000..01b0f9a107 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/public/robots.txt @@ -0,0 +1,2 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * diff --git a/packages/create-app/templates/default-app/packages/app-next/public/safari-pinned-tab.svg b/packages/create-app/templates/default-app/packages/app-next/public/safari-pinned-tab.svg new file mode 100644 index 0000000000..0f500b3002 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/public/safari-pinned-tab.svg @@ -0,0 +1 @@ +Created by potrace 1.11, written by Peter Selinger 2001-2013 \ No newline at end of file diff --git a/packages/create-app/templates/default-app/packages/app-next/src/App.test.tsx b/packages/create-app/templates/default-app/packages/app-next/src/App.test.tsx new file mode 100644 index 0000000000..ee456e1d72 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/src/App.test.tsx @@ -0,0 +1,51 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { renderWithEffects } from '@backstage/test-utils'; + +// Rarely, and only in windows CI, do these tests take slightly more than the +// default five seconds +jest.setTimeout(15_000); + +describe('App', () => { + it('should render', async () => { + process.env = { + NODE_ENV: 'test', + APP_CONFIG: [ + { + data: { + app: { + title: 'Test', + support: { url: 'http://localhost:7007/support' }, + }, + backend: { baseUrl: 'http://localhost:7007' }, + lighthouse: { + baseUrl: 'http://localhost:3003', + }, + techdocs: { + storageUrl: 'http://localhost:7007/api/techdocs/static/docs', + }, + }, + context: 'test', + }, + ] as any, + }; + + const { default: app } = await import('./App'); + const rendered = await renderWithEffects(app); + expect(rendered.baseElement).toBeInTheDocument(); + }); +}); diff --git a/packages/create-app/templates/default-app/packages/app-next/src/App.tsx b/packages/create-app/templates/default-app/packages/app-next/src/App.tsx new file mode 100644 index 0000000000..5a3611ba65 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/src/App.tsx @@ -0,0 +1,67 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApp } from '@backstage/frontend-defaults'; +import apiDocsPlugin from '@backstage/plugin-api-docs/alpha'; +import appVisualizerPlugin from '@backstage/plugin-app-visualizer'; +import catalogPlugin from '@backstage/plugin-catalog/alpha'; +import catalogGraphPlugin from '@backstage/plugin-catalog-graph/alpha'; +import catalogImportPlugin from '@backstage/plugin-catalog-import/alpha'; +import homePlugin from '@backstage/plugin-home/alpha'; +import kubernetesPlugin from '@backstage/plugin-kubernetes/alpha'; +import orgPlugin from '@backstage/plugin-org/alpha'; +import scaffolderPlugin from '@backstage/plugin-scaffolder/alpha'; +import searchPlugin from '@backstage/plugin-search/alpha'; +import techdocsPlugin from '@backstage/plugin-techdocs/alpha'; +import userSettingsPlugin from '@backstage/plugin-user-settings/alpha'; + +import { createFrontendModule, PageBlueprint } from '@backstage/frontend-plugin-api'; +import { Navigate } from 'react-router'; + + +// This just defaults to `/catalog` instead of a blank page +const defaultPageExtension = PageBlueprint.make({ + name: 'default', + params: { + defaultPath: '/', + loader: () => Promise.resolve(), + }, +}); + +const app = createApp({ + features: [ + searchPlugin, + orgPlugin, + catalogPlugin, + apiDocsPlugin, + techdocsPlugin, + scaffolderPlugin, + homePlugin, + kubernetesPlugin, + catalogGraphPlugin, + catalogImportPlugin, + appVisualizerPlugin, + userSettingsPlugin, + createFrontendModule({ + pluginId: 'app', + extensions: [ + defaultPageExtension + ], + }), + ], +}); + +export default app.createRoot(); diff --git a/packages/create-app/templates/default-app/packages/app-next/src/index.tsx b/packages/create-app/templates/default-app/packages/app-next/src/index.tsx new file mode 100644 index 0000000000..82b9595c84 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/src/index.tsx @@ -0,0 +1,22 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@backstage/cli/asset-types'; +import ReactDOM from 'react-dom/client'; +import app from './App'; +import '@backstage/canon/css/styles.css'; + +ReactDOM.createRoot(document.getElementById('root')!).render(app); diff --git a/packages/create-app/templates/default-app/packages/app-next/src/setupTests.ts b/packages/create-app/templates/default-app/packages/app-next/src/setupTests.ts new file mode 100644 index 0000000000..23fcbe9676 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app-next/src/setupTests.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index c95b8294c7..f580281558 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -43,6 +43,7 @@ const templatePackagePaths = [ 'packages/cli/templates/frontend-plugin/package.json.hbs', 'packages/create-app/templates/default-app/package.json.hbs', 'packages/create-app/templates/default-app/packages/app/package.json.hbs', + 'packages/create-app/templates/default-app/packages/app-next/package.json.hbs', 'packages/create-app/templates/default-app/packages/backend/package.json.hbs', ];