Skip to content

Commit 866c732

Browse files
authored
Merge pull request #798 from cacheplane/feat/langgraph-app-mode-itinerary
Add app-mode itinerary demo and markdown coverage
2 parents 7ee0b44 + 97f86b9 commit 866c732

4 files changed

Lines changed: 50 additions & 4 deletions

File tree

examples/chat/angular/e2e/fixtures/markdown.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
"match": { "userMessage": "respond with a bullet list" },
1313
"response": { "content": "Three things:\n\n- alpha\n- beta\n- gamma" }
1414
},
15+
{
16+
"match": {
17+
"userMessage": "Give me a blockquote with two lines, then a markdown table with columns issue, expected behavior, verification."
18+
},
19+
"response": {
20+
"content": "> First quoted line\n> Second quoted line\n\n| Issue | Expected behavior | Verification |\n| --- | --- | --- |\n| Blockquote nesting | Both quoted lines render inside one blockquote | Inspect for one `<blockquote>` with no stray quoted paragraph |\n| Table streaming | Rows remain inside the same table while content streams | Inspect for one `<table>` with body rows |\n| Parser recovery | Final DOM has no raw pipe paragraphs | Confirm no paragraph text contains `|` delimiters |"
21+
}
22+
},
1523
{
1624
"match": { "userMessage": "respond with the markdown checklist kitchen sink" },
1725
"response": {

examples/chat/angular/e2e/markdown-surfaces.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,29 @@ test('markdown checklist matrix: rich markdown renders with escaped html', async
6262
await expect(bubble).toContainText("<script>alert('xss')</script>");
6363
});
6464

65+
test('blockquote followed by table stays in one rendered markdown surface', async ({ page }) => {
66+
const bubble = await sendPromptAndWait(
67+
page,
68+
'Give me a blockquote with two lines, then a markdown table with columns issue, expected behavior, verification.',
69+
);
70+
71+
await expect(bubble.locator('blockquote')).toHaveCount(1);
72+
await expect(bubble.locator('blockquote')).toContainText('First quoted line');
73+
await expect(bubble.locator('blockquote')).toContainText('Second quoted line');
74+
await expect(bubble.locator('table')).toHaveCount(1);
75+
await expect(bubble.locator('thead th')).toHaveText([
76+
'Issue',
77+
'Expected behavior',
78+
'Verification',
79+
]);
80+
await expect(bubble.locator('tbody tr')).toHaveCount(3);
81+
await expect.poll(async () => tableColumnsAlign(bubble)).toBe(true);
82+
await expect(
83+
bubble.locator('p').filter({ hasText: /\|/ }),
84+
'table rows should not render as raw pipe paragraphs',
85+
).toHaveCount(0);
86+
});
87+
6588
test('streaming markdown table: keeps in-progress rows inside one table', async ({ page }) => {
6689
const hygiene = attachBrowserHygiene(page);
6790
await sendPrompt(page, 'stream a markdown comparison table regression');
@@ -94,13 +117,19 @@ test('streaming markdown table: blockquote followed by table does not throw', as
94117
const bubble = await waitForFinalAssistant(page);
95118
await expect(bubble.locator('blockquote')).toBeVisible();
96119
await expect(bubble.locator('blockquote')).toContainText('First line of the quote.');
120+
await expect(bubble.locator('blockquote')).toContainText('Second line of the quote.');
97121
await expect(bubble.locator('table')).toHaveCount(1);
98122
await expect(bubble.locator('thead th')).toHaveText([
99123
'Issue',
100124
'Expected behavior',
101125
'Verification',
102126
]);
103127
await expect(bubble.locator('tbody tr')).toHaveCount(2);
128+
await expect.poll(async () => tableColumnsAlign(bubble)).toBe(true);
129+
await expect(
130+
bubble.locator('p').filter({ hasText: /\|/ }),
131+
'table rows should not render as raw pipe paragraphs',
132+
).toHaveCount(0);
104133
expect(hygiene.consoleErrors).toEqual([]);
105134
expect(hygiene.failedRequests).toEqual([]);
106135
});

libs/chat/src/lib/styles/chat-sidenav.styles.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ describe('CHAT_SIDENAV_STYLES — drawer elevation + z-index token', () => {
9494
it('no longer declares the .chat-sidenav__scrim selector', () => {
9595
expect(normalized).not.toMatch(/\.chat-sidenav__scrim\s*\{/);
9696
});
97+
it('keeps the closed drawer panel inert until the drawer is open', () => {
98+
expect(normalized).toMatch(
99+
/:host\(\[data-mode="drawer"\]\) \.chat-sidenav\s*\{[^}]*pointer-events:\s*none\s*;/,
100+
);
101+
expect(normalized).toMatch(
102+
/:host\(\[data-mode="drawer"\]\[data-open="true"\]\) \.chat-sidenav\s*\{[^}]*pointer-events:\s*auto\s*;/,
103+
);
104+
});
97105
});
98106

99107
describe('CHAT_SIDENAV_STYLES — Archived disclosure', () => {

libs/chat/src/lib/styles/chat-sidenav.styles.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@ export const CHAT_SIDENAV_STYLES = `
6565
height: 100%;
6666
transition: transform 200ms ease;
6767
transform: translateX(-100%);
68-
/* Re-enable pointer events on the panel itself (host is inert above). When
69-
* closed the panel is translated off-screen so this is harmless; when open
70-
* it covers the host box and stays fully interactive. */
71-
pointer-events: auto;
68+
/* Keep the closed/closing panel inert. The host is inert above, and the
69+
* panel can still be hit during its transform transition unless pointer
70+
* events are restored only for the open state below. */
71+
pointer-events: none;
7272
}
7373
:host([data-mode="drawer"][data-open="true"]) .chat-sidenav {
7474
transform: translateX(0);
75+
pointer-events: auto;
7576
}
7677
.chat-sidenav__header {
7778
flex-shrink: 0;

0 commit comments

Comments
 (0)