@@ -840,6 +876,8 @@ const scenarioStepCountsByJourney: Record> = Obje
const journey = manifest.journeys.find((item) => item.id === state.journeyId) || manifest.journeys[0];
const scenario = manifest.scenarios.find((item) => item.id === state.scenarioId) || manifest.scenarios[0];
const stepIndex = visibleFlow.indexOf(activeStep.key);
+ const visibleJourneyIds = ['all', ...((journey && journey.contentJourneyIds) || [])];
+ root.dataset.workshopVisibleJourneys = [...new Set(visibleJourneyIds)].join(' ');
if (tunnelPanel) {
tunnelPanel.hidden = state.journeyId !== 'vscode' || setupStep !== 'scenario';
}
@@ -1307,6 +1345,19 @@ const scenarioStepCountsByJourney: Record> = Obje
min-height: 22rem;
}
+ .aw-workshop-step-content :global(.aw-workshop-journey-block) {
+ display: none;
+ }
+
+ .aw-workshop-step-content :global(.aw-workshop-journey-block.aw-workshop-journey-block-all),
+ .aw-workshop[data-workshop-visible-journeys~='ui'] .aw-workshop-step-content :global(.aw-workshop-journey-block.aw-workshop-journey-block-ui),
+ .aw-workshop[data-workshop-visible-journeys~='terminal'] .aw-workshop-step-content :global(.aw-workshop-journey-block.aw-workshop-journey-block-terminal),
+ .aw-workshop[data-workshop-visible-journeys~='local'] .aw-workshop-step-content :global(.aw-workshop-journey-block.aw-workshop-journey-block-local),
+ .aw-workshop[data-workshop-visible-journeys~='codespace'] .aw-workshop-step-content :global(.aw-workshop-journey-block.aw-workshop-journey-block-codespace),
+ .aw-workshop[data-workshop-visible-journeys~='copilot'] .aw-workshop-step-content :global(.aw-workshop-journey-block.aw-workshop-journey-block-copilot) {
+ display: contents;
+ }
+
.aw-workshop-step-content :global(h2),
.aw-workshop-step-content :global(h3),
.aw-workshop-step-content :global(h4) {
diff --git a/docs/tests/workshop.spec.ts b/docs/tests/workshop.spec.ts
index bae97d5b698..3a5bf3ea786 100644
--- a/docs/tests/workshop.spec.ts
+++ b/docs/tests/workshop.spec.ts
@@ -583,3 +583,143 @@ test.describe('Workshop flow filtering: Copilot scenario-d substitution', () =>
expect(keys).not.toContain('11c-build-pr-reviewer-ui');
});
});
+
+// ---------------------------------------------------------------------------
+// Journey block visibility tests — verify that CSS-driven journey section
+// visibility works correctly: marker rewriting, attribute state, and
+// visibility transitions when switching paths.
+// ---------------------------------------------------------------------------
+
+test.describe('Workshop journey block visibility', () => {
+ test('data-workshop-visible-journeys contains "all" and journey-specific IDs after starting the tutorial', async ({ page }) => {
+ // ui-learner maps to the github journey, which has contentJourneyIds: ['ui']
+ await startWorkshop(page);
+
+ const visibleJourneys = await page.evaluate(() =>
+ document.querySelector('[data-workshop-root]')?.getAttribute('data-workshop-visible-journeys') ?? '',
+ );
+ // 'all' is always included; 'ui' comes from the github journey's contentJourneyIds
+ expect(visibleJourneys.split(' ')).toContain('all');
+ expect(visibleJourneys.split(' ')).toContain('ui');
+ });
+
+ test('data-workshop-visible-journeys updates when switching to a different entry path', async ({ page }) => {
+ // Start with ui-learner (github journey → contentJourneyIds: ['ui'])
+ await startWorkshop(page);
+
+ const initialJourneys = await page.evaluate(() =>
+ document.querySelector('[data-workshop-root]')?.getAttribute('data-workshop-visible-journeys') ?? '',
+ );
+ expect(initialJourneys.split(' ')).toContain('ui');
+
+ // Switch to the terminal path (contentJourneyIds: ['terminal', 'local'])
+ await page.getByRole('button', { name: /Change route/i }).click();
+ await page.locator('[data-workshop-entry-path="cli-user"]').click();
+ await page.locator('[data-workshop-scenario="daily-status"]').click();
+ await expect(page.locator('[data-workshop-tutorial]')).toBeVisible();
+
+ const updatedJourneys = await page.evaluate(() =>
+ document.querySelector('[data-workshop-root]')?.getAttribute('data-workshop-visible-journeys') ?? '',
+ );
+ expect(updatedJourneys.split(' ')).toContain('all');
+ expect(updatedJourneys.split(' ')).toContain('terminal');
+ // 'ui' should no longer be listed (terminal journey does not map to ui content)
+ expect(updatedJourneys.split(' ')).not.toContain('ui');
+ });
+
+ test('no raw journey comment markers survive HTML rewriting in step data', async ({ page }) => {
+ await startWorkshop(page);
+
+ // Any or remaining in rendered HTML
+ // means rewriteJourneyBlocks did not run or failed. Raw markers must never
+ // appear in the embedded step-data JSON.
+ const hasRawMarkers = await page.evaluate(() => {
+ const node = document.getElementById('aw-workshop-step-data');
+ if (!node) return false;
+ const steps = JSON.parse(node.textContent?.trim() || '[]') as Array<{ html: string }>;
+ return steps.some((s) => /