Skip to content

Commit ac24c2b

Browse files
committed
Address PR #1327 review: harden selectors, merge changelog, add screenshots
- CorpusChat.tsx: use crypto.randomUUID() for SYNC_CONTENT fallback messageId; add aria-label to BackButton so tests can target it stably - CreateCorpusActionModal.tsx: export DEFAULT_MODERATOR_INSTRUCTIONS so the CT test imports it instead of duplicating the string - CorpusAgentManagement.ct.tsx: replace fragile .last() on Save Changes with role-based locator; add docScreenshot - CorpusChat.ct.tsx: replace XPath preceding::button selector with aria-label lookup; clarify that the title-filter debounce test is coverage-only - CreateCorpusActionModal.ct.tsx: import DEFAULT_MODERATOR_INSTRUCTIONS from source; comment the intentional invalid-trigger cast; add docScreenshot - CorpusDescriptionEditor.ct.tsx: add docScreenshot - CHANGELOG: merge duplicate ### Fixed sections into one block under ### Added
1 parent 6f8c62e commit ac24c2b

13 files changed

Lines changed: 31 additions & 26 deletions

CHANGELOG.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
### Fixed
11-
12-
- **`CorpusChat` dropped `SYNC_CONTENT` messages from the visible chat** (Issue #1276, `frontend/src/components/corpuses/CorpusChat.tsx:468-495`): The `SYNC_CONTENT` WebSocket frame is a standalone, non-streaming assistant reply used for synchronous server responses. `ChatTray` (document chat) appends these directly to its `chat` state; the corpus-level chat only forwarded the content to `handleCompleteMessage`, which stores sources in `ChatSourceAtom` but never pushes a message to the visible list. As a result, any `SYNC_CONTENT` the backend sent over the corpus socket rendered nothing. Fixed by mirroring the `ChatTray` pattern — push a new complete assistant message into `chat` before persisting sources/timeline. New regression test in `frontend/tests/CorpusChat.ct.tsx` ("SYNC_CONTENT renders a complete message immediately") pins the behavior.
13-
1410
### Added
1511

1612
- **Coverage: raise Corpus Chat & Agent Management component tests** (Issue #1276): added 36 new Playwright CT tests across the four lowest-ROI corpus components to drive coverage toward the ≥60% target. Breakdown:
@@ -20,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2016
- `frontend/tests/CorpusDescriptionEditor.ct.tsx` (+7 tests): save failure (`ok: false`), save network-error path, reapply of snapshot-less version, twice-click collapse, Cancel Version Edit reset, fetch-md URL failure, and version-count pluralization.
2117

2218
### Fixed
19+
20+
- **`CorpusChat` dropped `SYNC_CONTENT` messages from the visible chat** (Issue #1276, `frontend/src/components/corpuses/CorpusChat.tsx:468-495`): The `SYNC_CONTENT` WebSocket frame is a standalone, non-streaming assistant reply used for synchronous server responses. `ChatTray` (document chat) appends these directly to its `chat` state; the corpus-level chat only forwarded the content to `handleCompleteMessage`, which stores sources in `ChatSourceAtom` but never pushes a message to the visible list. As a result, any `SYNC_CONTENT` the backend sent over the corpus socket rendered nothing. Fixed by mirroring the `ChatTray` pattern — push a new complete assistant message into `chat` before persisting sources/timeline. New regression test in `frontend/tests/CorpusChat.ct.tsx` ("SYNC_CONTENT renders a complete message immediately") pins the behavior.
2321
- **Backend CI `changes` job failed on every push to main** (`.github/workflows/backend.yml`): `dorny/paths-filter@v3` was declared without a prior `actions/checkout`, on the stated premise that the action "fetches diffs via the GitHub API". That is only true for `pull_request` events; on `push` events the action shells out to `git branch --show-current`, which fails with `fatal: not a git repository` when the workspace is empty. Every push to a protected branch therefore produced a red X on the `changes` job, silently masked by `continue-on-error: true` plus a `|| github.event_name == 'push'` fail-open gate on downstream jobs. Scoped the `changes` job to `pull_request` events (`if: github.event_name == 'pull_request'`) — where paths-filter actually works — and rewrote the downstream gates on `linter` / `pytest` as `if: always() && (github.event_name == 'push' || needs.changes.outputs.backend != 'false')` so the skip cascade from a `needs`-target that is now intentionally skipped on push does not block the real test jobs. Behaviour preserved: push always runs `linter` + `pytest`; PRs with no backend changes still skip both; PRs where the filter errors transiently (outputs.backend == '') still fail open.
2422
- **Frontend CI tippy-debug step removed** (`.github/workflows/frontend.yml`): Dropped the `Debug - Check for tippy references` step in the `lint` job — a leftover investigation artifact that ran on every PR/push and produced noise with no diagnostic value today. Flagged in Issue #1319.
2523
- **Codecov-notify `matching[0]` relied on undocumented API ordering** (`.github/workflows/codecov-notify.yml`): The cross-workflow coordinator picked the "most recent" workflow run per expected name by indexing `matching[0]` on the filter result, leaning on the GitHub Actions REST API returning results newest-first. That ordering is not guaranteed. Added an explicit `created_at` descending sort before taking `matching[0]`, so re-run detection is correct regardless of API-side quirks. Flagged in Issue #1319.
55.3 KB
Loading
6.75 KB
Loading
1.65 KB
Loading
-678 Bytes
Loading
53.1 KB
Loading
53.8 KB
Loading

frontend/src/components/corpuses/CorpusChat.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,12 +466,12 @@ export const CorpusChat: React.FC<CorpusChatProps> = ({
466466
setIsProcessing(false);
467467
break;
468468
case "SYNC_CONTENT": {
469-
// SYNC_CONTENT is a standalone, non-streaming assistant message.
470-
// Append it to chat so it renders, then persist sources/timeline.
469+
// SYNC_CONTENT is a standalone (non-streaming) assistant reply — unlike the
470+
// ASYNC path, it must be appended to `chat` directly or it will never render.
471471
setChat((prev) => [
472472
...prev,
473473
{
474-
messageId: data?.message_id || `asst_${Date.now()}`,
474+
messageId: data?.message_id || crypto.randomUUID(),
475475
user: "Assistant",
476476
content,
477477
timestamp: new Date().toLocaleString(),
@@ -1007,6 +1007,7 @@ export const CorpusChat: React.FC<CorpusChatProps> = ({
10071007
{isConversation && (
10081008
<ChatNavigationHeader>
10091009
<BackButton
1010+
aria-label="Back to conversation list"
10101011
onClick={(e) => {
10111012
e.preventDefault();
10121013
e.stopPropagation();

frontend/src/components/corpuses/CreateCorpusActionModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const DEFAULT_MODERATION_TOOLS = [
7171
{ name: "unpin_thread", description: "Unpin a pinned thread" },
7272
] as const;
7373

74-
const DEFAULT_MODERATOR_INSTRUCTIONS = `You are a thread moderator for this corpus. Your role is to:
74+
export const DEFAULT_MODERATOR_INSTRUCTIONS = `You are a thread moderator for this corpus. Your role is to:
7575
1. Monitor discussion threads and messages for policy compliance
7676
2. Take appropriate moderation actions when needed
7777
3. Respond helpfully to user questions when appropriate

frontend/tests/CorpusAgentManagement.ct.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
DELETE_AGENT_CONFIGURATION,
99
UPDATE_AGENT_CONFIGURATION,
1010
} from "../src/graphql/mutations";
11+
import { docScreenshot } from "./utils/docScreenshot";
1112

1213
const TEST_CORPUS_ID = "corpus-aam-1";
1314

@@ -152,6 +153,8 @@ test.describe("CorpusAgentManagement", () => {
152153
await expect(page.getByLabel("Edit agent")).toBeVisible();
153154
await expect(page.getByLabel("Delete agent")).toBeVisible();
154155

156+
await docScreenshot(page, "corpus--agent-management--agent-row");
157+
155158
await component.unmount();
156159
});
157160

@@ -604,8 +607,7 @@ test.describe("CorpusAgentManagement", () => {
604607

605608
// Click Save Changes (modal footer button)
606609
await page
607-
.locator(".oc-modal button:has-text('Save Changes')")
608-
.last()
610+
.getByRole("button", { name: "Save Changes", exact: true })
609611
.click();
610612

611613
await expect(page.getByText("Agent updated successfully")).toBeVisible({

0 commit comments

Comments
 (0)