fix: show v13 onboarding immediately after Git migration completes [INS-2552] (#10050)

* fix: redirect users to onboarding or organization view after migration

* fix: adjust INSOMNIA_SKIP_ONBOARDING to allow onboarding flows

* test: add Git migration onboarding test case

* fix: safeguard post-migration path for server-side rendering
This commit is contained in:
Pavlos Koutoglou
2026-06-09 17:09:31 +02:00
committed by GitHub
parent a9c9216254
commit 7d5eb88ca0
3 changed files with 107 additions and 3 deletions

View File

@@ -72,7 +72,9 @@ export const test = baseTest.extend<{
INSOMNIA_GITLAB_API_URL: echoServer + '/gitlab-api',
INSOMNIA_UPDATES_URL: echoServer || 'https://updates.insomnia.rest',
INSOMNIA_MOCK_API_URL: 'https://mock-stage.insomnia.run',
INSOMNIA_SKIP_ONBOARDING: String(userConfig.skipOnboarding),
// Empty string (not "false") so the renderer's `if (skipOnboarding)` guard is falsy
// and onboarding flows can be exercised; "false" would be a truthy string.
INSOMNIA_SKIP_ONBOARDING: userConfig.skipOnboarding ? 'true' : '',
INSOMNIA_PUBLIC_KEY: userConfig.publicKey,
INSOMNIA_SECRET_KEY: userConfig.secretKey,
INSOMNIA_VAULT_KEY: userConfig.vaultKey || '',

View File

@@ -0,0 +1,93 @@
import fs from 'node:fs';
import path from 'node:path';
import { expect } from '@playwright/test';
import { test } from '../../playwright/test';
// Seeds a data directory with a single connected Git project whose GitRepository
// has no `repoMigrationVersion` stamp, so `getInitialEntry` treats it as having a
// pending Git filesystem migration and routes to `/git-migration` on launch.
//
// The repo has no on-disk `git/` or `other/` directories, so the structure
// migration is a no-op that completes successfully without needing real git files.
const seedPendingGitMigration = async (dataPath: string) => {
const now = Date.now();
// Legacy ('git_xxx') format on the project so getInitialEntry's `_id $in` query
// matches the GitRepository._id directly (this is the pre-migration layout).
const gitRepositoryId = 'git_smoketestpending';
const project = {
_id: 'proj_smoketestgit',
type: 'Project',
parentId: null,
modified: now,
created: now,
name: 'Git Migration Smoke Project',
remoteId: null,
gitRepositoryId,
};
const gitRepository = {
_id: gitRepositoryId,
type: 'GitRepository',
parentId: null,
modified: now,
created: now,
needsFullClone: false,
uri: 'https://github.com/example/insomnia-git-example.git',
credentials: null,
author: { name: '', email: '' },
uriNeedsMigration: false,
// Intentionally no `repoMigrationVersion` → treated as a pending migration.
};
await fs.promises.mkdir(dataPath, { recursive: true });
await fs.promises.writeFile(path.join(dataPath, 'insomnia.Project.db'), JSON.stringify(project) + '\n', 'utf8');
await fs.promises.writeFile(
path.join(dataPath, 'insomnia.GitRepository.db'),
JSON.stringify(gitRepository) + '\n',
'utf8',
);
};
const testWithPendingGitMigration = test.extend({
dataPath: async ({ dataPath }, use) => {
await seedPendingGitMigration(dataPath);
await use(dataPath);
},
userConfig: async ({ userConfig }, use) => {
await use({
...userConfig,
// Do not pre-mark onboarding as seen — we want the v13 onboarding to appear
// immediately after the migration completes.
skipOnboarding: false,
});
},
});
testWithPendingGitMigration(
'shows Git migration first, then the v13 onboarding immediately after it completes',
async ({ page }) => {
// Migration may take a moment; avoid timing out before the min-display window elapses.
test.slow();
// 1. The Git migration route is shown first (before the v13 onboarding).
await expect.soft(page.getByRole('heading', { name: "What's new in v12.6.0" })).toBeVisible();
// The v13 onboarding welcome must not be visible yet.
await expect.soft(page.getByRole('heading', { name: /Welcome to Insomnia 13/ })).toBeHidden();
await page.getByRole('button', { name: 'Continue' }).click();
// 2. Run the filesystem migration.
await expect.soft(page.getByRole('heading', { name: 'Required file system update' })).toBeVisible();
await page.getByRole('button', { name: 'Update Now' }).click();
// 3. Migration completes successfully.
await expect.soft(page.getByRole('heading', { name: 'Update Successful' })).toBeVisible({ timeout: 30_000 });
// 4. Opening Insomnia from the completed migration lands on the v13 onboarding.
await page.getByRole('link', { name: 'Open Insomnia' }).click();
await expect.soft(page.getByRole('heading', { name: /Welcome to Insomnia 13/ })).toBeVisible();
},
);

View File

@@ -49,6 +49,15 @@ const MigrationView = () => {
const isUpdateErrored = status === 'error';
const isUpdateCompletedWithErrors = status === 'partiallyCompleted';
// After the migration completes, send users straight into the v13 onboarding
// if they haven't seen it yet; otherwise go to the organization view.
// Guard `window` so this stays safe during SSR (entry.server.tsx) — the value is
// only read once the completion links render, which only happens client-side.
const postMigrationPath =
typeof window !== 'undefined' && window.localStorage.getItem('hasSeenOnboardingV13')
? '/organization'
: '/onboarding';
return (
<div className="flex h-full min-h-[500px] w-[600px] flex-col items-center justify-center">
<div className="relative flex w-full flex-col items-center justify-center gap-(--padding-sm) rounded-md border border-solid border-(--hl-sm) bg-(--hl-xs) p-8">
@@ -120,7 +129,7 @@ const MigrationView = () => {
{isUpdateCompletedSuccessfully ? (
<Link
className="flex h-full items-center justify-center gap-2 rounded-md border border-solid border-(--hl-md) bg-(--color-surprise) px-4 py-2 text-sm font-semibold text-(--color-font-surprise) ring-1 ring-transparent transition-all focus:ring-(--hl-md) focus:ring-inset aria-pressed:opacity-80"
to="/organization"
to={postMigrationPath}
>
Open Insomnia
</Link>
@@ -136,7 +145,7 @@ const MigrationView = () => {
</CopyButton>
<Link
className="flex h-full items-center justify-center gap-2 rounded-md border border-solid border-(--hl-md) bg-(--color-surprise) px-4 py-2 text-sm font-semibold text-(--color-font-surprise) ring-1 ring-transparent transition-all focus:ring-(--hl-md) focus:ring-inset aria-pressed:opacity-80"
to="/organization"
to={postMigrationPath}
>
Open Insomnia
</Link>