diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index f7dfbc946..d56c788b1 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -38,7 +38,7 @@ jobs: strategy: matrix: - test_target: [api, ui] + test_target: [api, ui, ui-cloud] runs-on: ubuntu-latest @@ -78,7 +78,11 @@ jobs: - name: Extract working-directory: tests run: | - npm run cli init -- -p ../logto --db postgres://postgres:postgres@localhost:5432/postgres --du ../logto.tar.gz + npm run cli init -- \ + -p ../logto \ + --db postgres://postgres:postgres@localhost:5432/postgres \ + --du ../logto.tar.gz \ + ${{ contains(matrix.test_target, 'cloud') && '--cloud' || '' }} - name: Check and add mock connectors working-directory: tests @@ -92,6 +96,13 @@ jobs: env: INTEGRATION_TEST: true + - name: Run Logto Cloud + working-directory: logto/ + if: contains(matrix.test_target, 'cloud') + run: nohup npm start:cloud > nohup-cloud.out 2> nohup-cloud.err < /dev/null & + env: + INTEGRATION_TEST: true + - name: Sleep for 5 seconds run: sleep 5 diff --git a/packages/cli/src/commands/install/index.ts b/packages/cli/src/commands/install/index.ts index 512af9b62..965ffe8c5 100644 --- a/packages/cli/src/commands/install/index.ts +++ b/packages/cli/src/commands/install/index.ts @@ -18,11 +18,11 @@ import { export type InstallArgs = { path?: string; skipSeed: boolean; - officialConnectors?: boolean; + cloud: boolean; downloadUrl?: string; }; -const installLogto = async ({ path, skipSeed, officialConnectors, downloadUrl }: InstallArgs) => { +const installLogto = async ({ path, skipSeed, downloadUrl, cloud }: InstallArgs) => { validateNodeVersion(); // Get instance path @@ -44,7 +44,7 @@ const installLogto = async ({ path, skipSeed, officialConnectors, downloadUrl }: )} command to seed database when ready.\n` ); } else { - await seedDatabase(instancePath); + await seedDatabase(instancePath, cloud); } // Save to dot env @@ -59,7 +59,7 @@ const install: CommandModule< { p?: string; ss: boolean; - oc?: boolean; + cloud: boolean; du?: string; } > = { @@ -78,10 +78,11 @@ const install: CommandModule< type: 'boolean', default: false, }, - oc: { - alias: 'official-connectors', - describe: 'Add official connectors after downloading Logto', + cloud: { + describe: 'Init Logto for cloud', type: 'boolean', + hidden: true, + default: false, }, du: { alias: 'download-url', @@ -90,8 +91,8 @@ const install: CommandModule< hidden: true, }, }), - handler: async ({ p, ss, oc, du }) => { - await installLogto({ path: p, skipSeed: ss, officialConnectors: oc, downloadUrl: du }); + handler: async ({ p, ss, cloud, du }) => { + await installLogto({ path: p, skipSeed: ss, cloud, downloadUrl: du }); }, }; diff --git a/packages/cli/src/commands/install/utils.ts b/packages/cli/src/commands/install/utils.ts index 75a7ce9e1..8fd41b9ba 100644 --- a/packages/cli/src/commands/install/utils.ts +++ b/packages/cli/src/commands/install/utils.ts @@ -133,7 +133,7 @@ export const decompress = async (toPath: string, tarPath: string) => { ); }; -export const seedDatabase = async (instancePath: string) => { +export const seedDatabase = async (instancePath: string, cloud: boolean) => { try { const pool = await createPoolAndDatabaseIfNeeded(); await seedByPool(pool); diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index f388aa28f..48caf600a 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -15,6 +15,7 @@ "test": "pnpm build && pnpm test:api && pnpm test:ui", "test:api": "pnpm test:only -i ./lib/tests/api", "test:ui": "pnpm test:only -i --config=jest.config.ui.js ./lib/tests/ui", + "test:ui-cloud": "pnpm test:only -i --config=jest.config.ui.js ./lib/tests/ui-cloud", "lint": "eslint --ext .ts src", "lint:report": "pnpm lint --format json --output-file report.json", "start": "pnpm test" diff --git a/packages/integration-tests/src/constants.ts b/packages/integration-tests/src/constants.ts index 319961cbc..337c48f72 100644 --- a/packages/integration-tests/src/constants.ts +++ b/packages/integration-tests/src/constants.ts @@ -6,6 +6,7 @@ export const logtoConsoleUrl = getEnv( 'INTEGRATION_TESTS_LOGTO_CONSOLE_URL', 'http://localhost:3002' ); +export const logtoCloudUrl = getEnv('INTEGRATION_TESTS_LOGTO_CLOUD_URL', 'http://localhost:3003'); export const discoveryUrl = `${logtoUrl}/oidc/.well-known/openid-configuration`; diff --git a/packages/integration-tests/src/tests/ui-cloud/smoke.test.ts b/packages/integration-tests/src/tests/ui-cloud/smoke.test.ts new file mode 100644 index 000000000..6a68a7fdb --- /dev/null +++ b/packages/integration-tests/src/tests/ui-cloud/smoke.test.ts @@ -0,0 +1,21 @@ +import { logtoCloudUrl, logtoConsoleUrl } from '#src/constants.js'; +import { generatePassword } from '#src/utils.js'; + +/** + * NOTE: This test suite assumes test cases will run sequentially (which is Jest default). + * Parallel execution will lead to errors. + */ +describe('smoke testing for cloud', () => { + const consoleUsername = 'admin'; + const consolePassword = generatePassword(); + const adminTenantUrl = logtoConsoleUrl; // In dev mode, the console URL is actually for admin tenant + + it('opens with app element and navigates to sign-in page', async () => { + const navigation = page.waitForNavigation({ waitUntil: 'networkidle0' }); + await page.goto(logtoCloudUrl); + await navigation; + + await expect(page.waitForSelector('#app')).resolves.not.toBeNull(); + expect(page.url()).toBe(new URL('sign-in', adminTenantUrl).href); + }); +}); diff --git a/packages/integration-tests/src/tests/ui/smoke.test.ts b/packages/integration-tests/src/tests/ui/smoke.test.ts index 37e8d5005..47b8c0ab8 100644 --- a/packages/integration-tests/src/tests/ui/smoke.test.ts +++ b/packages/integration-tests/src/tests/ui/smoke.test.ts @@ -1,6 +1,10 @@ import { logtoConsoleUrl } from '#src/constants.js'; import { generatePassword } from '#src/utils.js'; +/** + * NOTE: This test suite assumes test cases will run sequentially (which is Jest default). + * Parallel execution will lead to errors. + */ describe('smoke testing', () => { const consoleUsername = 'admin'; const consolePassword = generatePassword();