BER-3361: Remove members-forward release gate#27221
BER-3361: Remove members-forward release gate#27221jonatansberg wants to merge 13 commits intomainfrom
Conversation
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release This releases the React-owned /members routes while keeping Ember detail flows intact and deferring dead-code cleanup to the next stacked PR.
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release This aligns the import-route unit coverage with the released behavior after removing the members-forward flag.
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release This drops the extra routes test file so the release branch stays focused on the shipped members routing change.
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release The config and runtime changes already cover the flag removal, so this extra assertion only added noise to the branch.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR removes the Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
E2E Tests FailedTo view the Playwright test report locally, run: REPORT_DIR=$(mktemp -d) && gh run download 24124282464 -n playwright-report -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR" |
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release Reused the shared link active matcher for the React-owned members routes and dropped the bespoke pathname check.
E2E Tests FailedTo view the Playwright test report locally, run: REPORT_DIR=$(mktemp -d) && gh run download 24127132919 -n playwright-report -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR" |
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release The release branch moved /members out of the Ember test lane, so the auth acceptance tests now use an Ember-owned protected route and the analytics assertion matches the released React copy.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #27221 +/- ##
==========================================
- Coverage 73.07% 72.92% -0.15%
==========================================
Files 1541 1545 +4
Lines 122884 123694 +810
Branches 14801 14965 +164
==========================================
+ Hits 89798 90205 +407
- Misses 32090 32522 +432
+ Partials 996 967 -29
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
E2E Tests FailedTo view the Playwright test report locally, run: REPORT_DIR=$(mktemp -d) && gh run download 24129099035 -n playwright-report -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR" |
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release The old filter-actions Playwright spec still drove Ember-only members filter controls that no longer exist on the released React /members route, while equivalent bulk-label coverage already exists in the React members suite.
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release These Playwright tests still asserted the old Ember members list surface even though /members is now React-owned, and the retained Ember detail flows are covered by the remaining detail-focused specs.
E2E Tests FailedTo view the Playwright test report locally, run: REPORT_DIR=$(mktemp -d) && gh run download 24181947096 -n playwright-report -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR" |
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release Row clicks on the React members list were bypassing the back query string even though the rendered links already carried it. This shares one detail-hash builder between link and row navigation so retained Ember detail screens can return to the filtered list state.
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release The release branch still ran Ember-list import and export coverage even though those routes are no longer part of the shipped members list. This drops the dead import spec and keeps the export coverage focused on the React-owned members route.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (5)
ghost/admin/tests/acceptance/members-test.js (1)
11-11: Avoid disabling the entire acceptance suite withdescribe.skip.Line 11 currently skips every members acceptance test in this file, which drops CI coverage for still-supported
/membersbehavior and can hide regressions. Please keep the suite enabled and only skip/remove truly obsolete cases.Proposed minimal fix
-describe.skip('Acceptance: Members Test', function () { +describe('Acceptance: Members Test', function () {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ghost/admin/tests/acceptance/members-test.js` at line 11, The test suite is entirely disabled by using describe.skip for the 'Acceptance: Members Test' suite; change describe.skip to describe to re-enable the acceptance tests in members-test.js, and if certain individual specs are truly obsolete mark those with it.skip or remove them instead of skipping the whole suite (locate the top-level describe.skip('Acceptance: Members Test', ...) and update it accordingly).e2e/tests/admin/members/export.test.ts (1)
96-105: Extract repeated export metadata assertions into a shared helper.Both scenarios repeat the same assertions for IDs/timestamps and filename shape. Pulling that into one helper will reduce drift as export behavior evolves.
♻️ Optional refactor
+function assertExportMetadata( + suggestedFilename: string, + contentIds: RegExpMatchArray | null, + contentTimestamps: RegExpMatchArray | null, + expectedCount: number +) { + expect(contentIds).toHaveLength(expectedCount); + expect(contentTimestamps).toHaveLength(expectedCount); + expect(suggestedFilename.startsWith('members')).toBe(true); + expect(suggestedFilename.endsWith('.csv')).toBe(true); +} + test.describe('Ghost Admin - Members Export', () => { @@ - expect(contentIds).toHaveLength(MEMBERS_FIXTURE.length); - expect(contentTimestamps).toHaveLength(MEMBERS_FIXTURE.length); - expect(suggestedFilename.startsWith('members')).toBe(true); - expect(suggestedFilename.endsWith('.csv')).toBe(true); + assertExportMetadata(suggestedFilename, contentIds, contentTimestamps, MEMBERS_FIXTURE.length); @@ - expect(contentIds).toHaveLength(filteredMembers.length); - expect(contentTimestamps).toHaveLength(filteredMembers.length); - expect(suggestedFilename.startsWith('members')).toBe(true); - expect(suggestedFilename.endsWith('.csv')).toBe(true); + assertExportMetadata(suggestedFilename, contentIds, contentTimestamps, filteredMembers.length);Also applies to: 119-127
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@e2e/tests/admin/members/export.test.ts` around lines 96 - 105, Create a shared test helper that centralizes the repeated export assertions: move the checks referencing membersPage.exportMembers() results (suggestedFilename, content), extractDownloadedContentSpecifics(content) outputs (contentIds, contentTimestamps), and assertExportedMembers(content, MEMBERS_FIXTURE) into one function (e.g., assertExportedMembersMetadata or verifyExportDownload) and call it from both test sites; the helper should assert contentIds and contentTimestamps lengths equal MEMBERS_FIXTURE.length and that suggestedFilename startsWith 'members' and endsWith '.csv', then replace the duplicated assertions in the tests with a single call to this new helper.apps/admin/src/layout/app-sidebar/nav-content.tsx (2)
80-97: Extract the members base path to one constant.
'members'is now hardcoded in both theuseIsActiveLinkcall and the nav target. Pulling that into a shared constant will make future route cleanup less error-prone.♻️ Suggested cleanup
+const MEMBERS_ROUTE = 'members'; const LEGACY_MEMBERS_ACTIVE_ROUTES = ['member', 'member.new', 'members-activity']; ... -const isMembersRouteActive = useIsActiveLink({path: 'members', activeOnSubpath: true}); +const isMembersRouteActive = useIsActiveLink({path: MEMBERS_ROUTE, activeOnSubpath: true}); ... -const membersRoute = 'members'; +const membersRoute = MEMBERS_ROUTE;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/admin/src/layout/app-sidebar/nav-content.tsx` around lines 80 - 97, Extract the hardcoded 'members' string into a single constant (e.g., MEMBERS_ROUTE) and use that constant wherever the literal is used: replace the argument in useIsActiveLink({path: 'members', ...}) and the membersRoute assignment (currently membersRoute = 'members'), and any other occurrences in this file (e.g., references involving isMembersRouteActive or membersNavActive) so all member-route logic references the new MEMBERS_ROUTE constant consistently.
91-93: Please add regression coverage for the legacy active-route fallback.This branch is now what keeps the Members item highlighted on Ember-only detail/new/activity screens after the
/members-forwardremoval. A focused test here would make the follow-up cleanup much safer.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/admin/src/layout/app-sidebar/nav-content.tsx` around lines 91 - 93, Add a focused regression test for the legacy active-route fallback used by membersNavActive: exercise the branch where isMembersRouteActive is false so the code falls back to routing.isRouteActive(LEGACY_MEMBERS_ACTIVE_ROUTES), and assert the Members item remains highlighted when routing.isRouteActive returns true; also include cases where isMembersRouteActive is true but either hasActiveMemberView or membersExpanded cause the expression to resolve false to ensure the original Ember-only detail/new/activity screens remain covered. Mock or stub routing.isRouteActive and render the component (or call the selector) to assert expected boolean outcomes for membersNavActive across these permutations.ghost/admin/app/routes/member.js (1)
57-65: Truncated comment at line 57.The cleanup logic is correct. However, the comment "Make sure we clear" appears to be incomplete. Consider completing it to explain what's being cleared and why.
📝 Suggested comment improvement
- // Make sure we clear + // Make sure we clear navigation state when leaving the member route if (isExiting) { controller.set('backPath', null); controller.set('directlyFromAnalytics', false); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ghost/admin/app/routes/member.js` around lines 57 - 65, The comment "Make sure we clear" is incomplete—update it to briefly explain what and why is being cleared: when isExiting is true, we're resetting transient navigation state on the controller (clearing backPath and directlyFromAnalytics) and clearing postAnalytics if present to avoid leaking state between member route visits; modify the comment above the conditional that references isExiting and controller.postAnalytics (the block that sets backPath, directlyFromAnalytics, and postAnalytics to null/false) to a concise sentence like "Clear transient navigation and analytics state when exiting the route to avoid carrying state into the next visit."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@ghost/admin/app/controllers/member.js`:
- Around line 54-56: The current check this.backPath?.startsWith('/members') is
too permissive and can match unintended routes like '/members-forward'; tighten
validation by matching only the exact /members route or subpaths (e.g. use a
strict test like /^\/members(?:$|\/)/ or normalize and compare path segments)
before returning this.backPath so stale or manipulated back links cannot fall
through; update the conditional around this.backPath to use that stricter
pattern (reference: this.backPath and the startsWith check).
In `@ghost/admin/tests/acceptance/members/filter-test.js`:
- Line 16: The test suite is entirely skipped via describe.skip in the
Acceptance: Members filtering suite; remove or replace describe.skip in the
members/filter-test.js so the suite runs, then run the tests and either fix
failing tests (adapting selectors, test setup, or stubs referenced inside the
describe block) or, if a specific case truly must be skipped, change only that
individual it(...) to it.skip and add a linked follow-up issue ID in the test’s
comment; ensure you reference the top-level describe('Acceptance: Members
filtering', ...) and any failing nested tests when making fixes.
In `@ghost/admin/tests/acceptance/members/import-test.js`:
- Line 11: The test suite has been disabled via describe.skip in the Members
import acceptance test (describe.skip in members/import-test.js), which silences
all coverage; either re-enable the suite by changing describe.skip back to
describe so tests run, or if the suite is truly obsolete remove the entire
describe block; if re-enabling, update any assertions and route references
inside the suite (e.g., route transition expectations and controller/route
ownership checks within the tests) to match the new route ownership and paths so
the restored tests pass against the current implementation.
---
Nitpick comments:
In `@apps/admin/src/layout/app-sidebar/nav-content.tsx`:
- Around line 80-97: Extract the hardcoded 'members' string into a single
constant (e.g., MEMBERS_ROUTE) and use that constant wherever the literal is
used: replace the argument in useIsActiveLink({path: 'members', ...}) and the
membersRoute assignment (currently membersRoute = 'members'), and any other
occurrences in this file (e.g., references involving isMembersRouteActive or
membersNavActive) so all member-route logic references the new MEMBERS_ROUTE
constant consistently.
- Around line 91-93: Add a focused regression test for the legacy active-route
fallback used by membersNavActive: exercise the branch where
isMembersRouteActive is false so the code falls back to
routing.isRouteActive(LEGACY_MEMBERS_ACTIVE_ROUTES), and assert the Members item
remains highlighted when routing.isRouteActive returns true; also include cases
where isMembersRouteActive is true but either hasActiveMemberView or
membersExpanded cause the expression to resolve false to ensure the original
Ember-only detail/new/activity screens remain covered. Mock or stub
routing.isRouteActive and render the component (or call the selector) to assert
expected boolean outcomes for membersNavActive across these permutations.
In `@e2e/tests/admin/members/export.test.ts`:
- Around line 96-105: Create a shared test helper that centralizes the repeated
export assertions: move the checks referencing membersPage.exportMembers()
results (suggestedFilename, content), extractDownloadedContentSpecifics(content)
outputs (contentIds, contentTimestamps), and assertExportedMembers(content,
MEMBERS_FIXTURE) into one function (e.g., assertExportedMembersMetadata or
verifyExportDownload) and call it from both test sites; the helper should assert
contentIds and contentTimestamps lengths equal MEMBERS_FIXTURE.length and that
suggestedFilename startsWith 'members' and endsWith '.csv', then replace the
duplicated assertions in the tests with a single call to this new helper.
In `@ghost/admin/app/routes/member.js`:
- Around line 57-65: The comment "Make sure we clear" is incomplete—update it to
briefly explain what and why is being cleared: when isExiting is true, we're
resetting transient navigation state on the controller (clearing backPath and
directlyFromAnalytics) and clearing postAnalytics if present to avoid leaking
state between member route visits; modify the comment above the conditional that
references isExiting and controller.postAnalytics (the block that sets backPath,
directlyFromAnalytics, and postAnalytics to null/false) to a concise sentence
like "Clear transient navigation and analytics state when exiting the route to
avoid carrying state into the next visit."
In `@ghost/admin/tests/acceptance/members-test.js`:
- Line 11: The test suite is entirely disabled by using describe.skip for the
'Acceptance: Members Test' suite; change describe.skip to describe to re-enable
the acceptance tests in members-test.js, and if certain individual specs are
truly obsolete mark those with it.skip or remove them instead of skipping the
whole suite (locate the top-level describe.skip('Acceptance: Members Test', ...)
and update it accordingly).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e61c4aa8-7850-4d7f-b1e9-5ea6a1d99938
⛔ Files ignored due to path filters (1)
ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snapis excluded by!**/*.snap
📒 Files selected for processing (44)
apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsxapps/admin/src/layout/app-sidebar/nav-content.tsxapps/admin/src/members-route-gate.tsxapps/admin/src/members-route.test.tsxapps/admin/src/members-route.tsxapps/admin/src/routes.tsxapps/posts/src/views/members/components/members-actions.tsxapps/posts/src/views/members/components/members-list-item.tsxapps/posts/src/views/members/components/members-list.tsxapps/posts/src/views/members/member-detail-hash.tsapps/posts/src/views/members/members.tsxapps/posts/test/unit/views/members/members-actions.test.tsxapps/posts/test/unit/views/members/members-list.test.tse2e/helpers/pages/admin/members/member-details-page.tse2e/tests/admin/analytics/post-analytics/growth.test.tse2e/tests/admin/members-legacy/disable-commenting.test.tse2e/tests/admin/members-legacy/filter-actions.test.tse2e/tests/admin/members-legacy/impersonation.test.tse2e/tests/admin/members-legacy/import.test.tse2e/tests/admin/members-legacy/member-activity-events.test.tse2e/tests/admin/members-legacy/members.test.tse2e/tests/admin/members-legacy/stripe-webhooks.test.tse2e/tests/admin/members/bulk-actions.test.tse2e/tests/admin/members/export.test.tse2e/tests/admin/members/list.test.tse2e/tests/admin/members/multiselect-filters.test.tse2e/tests/admin/members/saved-views.test.tse2e/tests/admin/members/search-and-filter.test.tse2e/tests/admin/members/tier-filter-search.test.tse2e/tests/admin/members/virtual-window.test.tsghost/admin/app/components/dashboard/onboarding-checklist.hbsghost/admin/app/components/editor/publish-options/publish-type.hbsghost/admin/app/components/posts-list/list-item.hbsghost/admin/app/controllers/member.jsghost/admin/app/router.jsghost/admin/app/routes/member.jsghost/admin/app/routes/members.jsghost/admin/app/services/feature.jsghost/admin/app/templates/member.hbsghost/admin/tests/acceptance/authentication-test.jsghost/admin/tests/acceptance/members-test.jsghost/admin/tests/acceptance/members/filter-test.jsghost/admin/tests/acceptance/members/import-test.jsghost/core/core/shared/labs.js
💤 Files with no reviewable changes (18)
- e2e/tests/admin/members/saved-views.test.ts
- e2e/tests/admin/members/search-and-filter.test.ts
- apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsx
- e2e/tests/admin/members/virtual-window.test.ts
- apps/admin/src/members-route-gate.tsx
- ghost/admin/app/router.js
- e2e/tests/admin/members-legacy/impersonation.test.ts
- ghost/admin/app/routes/members.js
- e2e/tests/admin/members/tier-filter-search.test.ts
- apps/admin/src/routes.tsx
- ghost/admin/app/services/feature.js
- e2e/tests/admin/members-legacy/disable-commenting.test.ts
- e2e/tests/admin/members-legacy/members.test.ts
- e2e/tests/admin/members-legacy/import.test.ts
- e2e/tests/admin/members-legacy/filter-actions.test.ts
- e2e/tests/admin/members/bulk-actions.test.ts
- ghost/core/core/shared/labs.js
- e2e/tests/admin/members-legacy/member-activity-events.test.ts
| if (this.backPath?.startsWith('/members')) { | ||
| return this.backPath; | ||
| } |
There was a problem hiding this comment.
Tighten backPath validation to avoid invalid route fallthrough.
Line 54 uses startsWith('/members'), which also accepts removed/non-list paths like /members-forward.... That can send delete/breadcrumb navigation to stale routes if back is manipulated or old links are used.
Suggested fix
- if (this.backPath?.startsWith('/members')) {
+ if (this.backPath?.match(/^\/members(?:$|\?)/)) {
return this.backPath;
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ghost/admin/app/controllers/member.js` around lines 54 - 56, The current
check this.backPath?.startsWith('/members') is too permissive and can match
unintended routes like '/members-forward'; tighten validation by matching only
the exact /members route or subpaths (e.g. use a strict test like
/^\/members(?:$|\/)/ or normalize and compare path segments) before returning
this.backPath so stale or manipulated back links cannot fall through; update the
conditional around this.backPath to use that stricter pattern (reference:
this.backPath and the startsWith check).
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release Removed redundant nav wiring, simplified the member detail path helper naming, and dropped the stale members-route e2e case without changing runtime behavior.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/admin/src/layout/app-sidebar/nav-content.tsx (1)
80-80: Optional: centralize the"members"route literal.Using one constant for the route path would reduce drift risk between active-state checks and link targets.
♻️ Suggested refactor
+const MEMBERS_ROUTE_PATH = 'members'; const LEGACY_MEMBERS_ACTIVE_ROUTES = ['member', 'member.new', 'members-activity']; -const isMembersRouteActive = useIsActiveLink({path: 'members', activeOnSubpath: true}); +const isMembersRouteActive = useIsActiveLink({path: MEMBERS_ROUTE_PATH, activeOnSubpath: true}); ... - to="members" + to={MEMBERS_ROUTE_PATH} ... - to="members" + to={MEMBERS_ROUTE_PATH}Also applies to: 183-197
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/admin/src/layout/app-sidebar/nav-content.tsx` at line 80, The "members" route string is repeated (e.g., in the isMembersRouteActive useIsActiveLink call and elsewhere around lines 183-197), which risks drift; extract that literal into a single constant (e.g., MEMBERS_ROUTE or MEMBERS_PATH) and replace all occurrences where the route is referenced (for active-state checks like isMembersRouteActive and any Link/Href targets) so both use the same identifier; update import/exports if needed so the constant is shared where used.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/admin/src/layout/app-sidebar/nav-content.tsx`:
- Line 80: The "members" route string is repeated (e.g., in the
isMembersRouteActive useIsActiveLink call and elsewhere around lines 183-197),
which risks drift; extract that literal into a single constant (e.g.,
MEMBERS_ROUTE or MEMBERS_PATH) and replace all occurrences where the route is
referenced (for active-state checks like isMembersRouteActive and any Link/Href
targets) so both use the same identifier; update import/exports if needed so the
constant is shared where used.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 115fe09e-99b1-4d52-8702-3a5d5594054d
📒 Files selected for processing (6)
apps/admin/src/layout/app-sidebar/nav-content.tsxapps/posts/src/views/members/components/members-list-item.tsxapps/posts/src/views/members/components/members-list.tsxapps/posts/src/views/members/member-detail-hash.tsapps/posts/test/unit/views/members/members-list.test.tse2e/tests/admin/members/list.test.ts
✅ Files skipped from review due to trivial changes (3)
- apps/posts/test/unit/views/members/members-list.test.ts
- apps/posts/src/views/members/member-detail-hash.ts
- apps/posts/src/views/members/components/members-list.tsx
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release Migrated the dropped React import flow and retained legacy member-detail coverage, and tightened bulk-action coverage so the filtered-members behavior still has an active browser test.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
e2e/tests/admin/members/import.test.ts (1)
16-31: Optional: clean up temporary CSV files after test execution.The temp file created around Line 29–Line 30 is never removed. Wrapping import steps in
try/finallywithunlinkSync(csvPath)would avoid local/CI temp-dir buildup over time.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@e2e/tests/admin/members/import.test.ts` around lines 16 - 31, The test creates a temp CSV via tmpdir() and writeFileSync into csvPath but never deletes it; wrap the import and assertions that use csvPath (the block around the import steps in import.test.ts) in a try/finally and call unlinkSync(csvPath) in the finally to ensure cleanup; reference csvPath, writeFileSync and tmpdir() to locate the creation and add unlinkSync(csvPath) to the finally block so temp files are removed even if the test fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@e2e/tests/admin/members/import.test.ts`:
- Around line 16-31: The test creates a temp CSV via tmpdir() and writeFileSync
into csvPath but never deletes it; wrap the import and assertions that use
csvPath (the block around the import steps in import.test.ts) in a try/finally
and call unlinkSync(csvPath) in the finally to ensure cleanup; reference
csvPath, writeFileSync and tmpdir() to locate the creation and add
unlinkSync(csvPath) to the finally block so temp files are removed even if the
test fails.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 661ddbaa-1ca4-4f55-b780-933798c60b03
📒 Files selected for processing (3)
e2e/tests/admin/members-legacy/members.test.tse2e/tests/admin/members/bulk-actions.test.tse2e/tests/admin/members/import.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- e2e/tests/admin/members-legacy/members.test.ts
- e2e/tests/admin/members/bulk-actions.test.ts
E2E Tests FailedTo view the Playwright test report locally, run: REPORT_DIR=$(mktemp -d) && gh run download 24190425447 -n playwright-report -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR" |
ref https://linear.app/ghost/issue/BER-3361/remove-feature-flag-release Updated the Playwright import modal helper to match the shipped React import dialog instead of the old Ember data-test selectors so the restored browser coverage exercises the real UI.
|



Summary
This PR removes the
membersForwardrollout machinery and the/members-forwardroute so the released React members experience owns/membersand/members/importdirectly.What changed
membersForwardlabs flag and related feature-service/settings exposure/members-forwardroute so React owns the released members routes directlybackpathWhy
BER-3506 landed the route handoff foundation. This branch finishes the release by deleting the rollout gate and flag-specific behavior without mixing in the broader Ember dead-code cleanup.
Testing
YARN_IGNORE_ENGINES=1 yarn workspace @tryghost/admin test:unit src/members-route.test.tsxYARN_IGNORE_ENGINES=1 yarn workspace @tryghost/posts exec vitest run test/unit/views/members/members-actions.test.tsxcd ghost/core && YARN_IGNORE_ENGINES=1 yarn test:single test/unit/shared/labs.test.jsYARN_IGNORE_ENGINES=1 yarn workspace @tryghost/e2e test:types