mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-12 01:02:39 +02:00
refactor(tests): simplify logging messages and enhance manual upload journey tests
This commit is contained in:
parent
66eebf614f
commit
2f540ee065
5 changed files with 117 additions and 7 deletions
|
|
@ -44,6 +44,10 @@ SLACK_CANARY_CHANNEL = "slack-e2e-canary"
|
||||||
CLICKUP_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_CLICKUP_001"
|
CLICKUP_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_CLICKUP_001"
|
||||||
CLICKUP_CANARY_TITLE = "E2E Canary ClickUp Task"
|
CLICKUP_CANARY_TITLE = "E2E Canary ClickUp Task"
|
||||||
CLICKUP_CANARY_TASK_ID = "fake-clickup-task-canary-001"
|
CLICKUP_CANARY_TASK_ID = "fake-clickup-task-canary-001"
|
||||||
|
MANUAL_UPLOAD_MD_CANARY_TOKEN = "E2E-MANUAL-UPLOAD-MD-CANARY-7f3a"
|
||||||
|
MANUAL_UPLOAD_MD_CANARY_FILE = "canary.md"
|
||||||
|
MANUAL_UPLOAD_PDF_CANARY_TOKEN = "E2E-MANUAL-UPLOAD-PDF-CANARY-9d2b"
|
||||||
|
MANUAL_UPLOAD_PDF_CANARY_FILE = "canary.pdf"
|
||||||
NO_RELEVANT_CONTENT_SENTINEL = "No relevant indexed content found."
|
NO_RELEVANT_CONTENT_SENTINEL = "No relevant indexed content found."
|
||||||
NO_RELEVANT_CONTENT_QUERY = "E2E_NO_RELEVANT_CONTENT_SMOKE"
|
NO_RELEVANT_CONTENT_QUERY = "E2E_NO_RELEVANT_CONTENT_SMOKE"
|
||||||
|
|
||||||
|
|
@ -208,6 +212,30 @@ class FakeChatLLM(BaseChatModel):
|
||||||
latest_human,
|
latest_human,
|
||||||
("clickup", CLICKUP_CANARY_TITLE),
|
("clickup", CLICKUP_CANARY_TITLE),
|
||||||
)
|
)
|
||||||
|
wants_manual_upload = _contains_any(
|
||||||
|
latest_human,
|
||||||
|
(
|
||||||
|
"uploaded",
|
||||||
|
"manual upload",
|
||||||
|
MANUAL_UPLOAD_MD_CANARY_FILE,
|
||||||
|
MANUAL_UPLOAD_PDF_CANARY_FILE,
|
||||||
|
MANUAL_UPLOAD_MD_CANARY_TOKEN,
|
||||||
|
MANUAL_UPLOAD_PDF_CANARY_TOKEN,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
wants_manual_upload_pdf = wants_manual_upload and _contains_any(
|
||||||
|
latest_human,
|
||||||
|
("pdf", MANUAL_UPLOAD_PDF_CANARY_FILE, MANUAL_UPLOAD_PDF_CANARY_TOKEN),
|
||||||
|
)
|
||||||
|
wants_manual_upload_md = wants_manual_upload and _contains_any(
|
||||||
|
latest_human,
|
||||||
|
(
|
||||||
|
"markdown",
|
||||||
|
".md",
|
||||||
|
MANUAL_UPLOAD_MD_CANARY_FILE,
|
||||||
|
MANUAL_UPLOAD_MD_CANARY_TOKEN,
|
||||||
|
),
|
||||||
|
)
|
||||||
has_gmail_evidence = (
|
has_gmail_evidence = (
|
||||||
GMAIL_CANARY_SUBJECT in prompt_text
|
GMAIL_CANARY_SUBJECT in prompt_text
|
||||||
or GMAIL_CANARY_MESSAGE_ID in prompt_text
|
or GMAIL_CANARY_MESSAGE_ID in prompt_text
|
||||||
|
|
@ -285,6 +313,14 @@ class FakeChatLLM(BaseChatModel):
|
||||||
or CLICKUP_CANARY_TOKEN in prompt_text
|
or CLICKUP_CANARY_TOKEN in prompt_text
|
||||||
or CLICKUP_CANARY_TASK_ID in prompt_text
|
or CLICKUP_CANARY_TASK_ID in prompt_text
|
||||||
)
|
)
|
||||||
|
has_manual_upload_md_evidence = (
|
||||||
|
MANUAL_UPLOAD_MD_CANARY_FILE in prompt_text
|
||||||
|
or MANUAL_UPLOAD_MD_CANARY_TOKEN in prompt_text
|
||||||
|
)
|
||||||
|
has_manual_upload_pdf_evidence = (
|
||||||
|
MANUAL_UPLOAD_PDF_CANARY_FILE in prompt_text
|
||||||
|
or MANUAL_UPLOAD_PDF_CANARY_TOKEN in prompt_text
|
||||||
|
)
|
||||||
|
|
||||||
if wants_clickup and has_clickup_evidence:
|
if wants_clickup and has_clickup_evidence:
|
||||||
return f"ClickUp content found: {CLICKUP_CANARY_TOKEN}"
|
return f"ClickUp content found: {CLICKUP_CANARY_TOKEN}"
|
||||||
|
|
@ -316,6 +352,10 @@ class FakeChatLLM(BaseChatModel):
|
||||||
return f"Drive PDF content found: {COMPOSIO_DRIVE_PDF_CANARY_TOKEN}"
|
return f"Drive PDF content found: {COMPOSIO_DRIVE_PDF_CANARY_TOKEN}"
|
||||||
if wants_drive and has_drive_evidence:
|
if wants_drive and has_drive_evidence:
|
||||||
return f"Drive content found: {DRIVE_CANARY_TOKEN}"
|
return f"Drive content found: {DRIVE_CANARY_TOKEN}"
|
||||||
|
if wants_manual_upload_pdf and has_manual_upload_pdf_evidence:
|
||||||
|
return f"Manual upload PDF content found: {MANUAL_UPLOAD_PDF_CANARY_TOKEN}"
|
||||||
|
if wants_manual_upload_md and has_manual_upload_md_evidence:
|
||||||
|
return f"Manual upload MD content found: {MANUAL_UPLOAD_MD_CANARY_TOKEN}"
|
||||||
if (
|
if (
|
||||||
has_notion_evidence
|
has_notion_evidence
|
||||||
and not has_confluence_evidence
|
and not has_confluence_evidence
|
||||||
|
|
@ -468,6 +508,36 @@ class FakeChatLLM(BaseChatModel):
|
||||||
and not has_slack_evidence
|
and not has_slack_evidence
|
||||||
):
|
):
|
||||||
return f"ClickUp content found: {CLICKUP_CANARY_TOKEN}"
|
return f"ClickUp content found: {CLICKUP_CANARY_TOKEN}"
|
||||||
|
if (
|
||||||
|
has_manual_upload_pdf_evidence
|
||||||
|
and not has_confluence_evidence
|
||||||
|
and not has_jira_evidence
|
||||||
|
and not has_linear_evidence
|
||||||
|
and not has_notion_evidence
|
||||||
|
and not has_calendar_evidence
|
||||||
|
and not has_gmail_evidence
|
||||||
|
and not has_drive_evidence
|
||||||
|
and not has_onedrive_evidence
|
||||||
|
and not has_dropbox_evidence
|
||||||
|
and not has_slack_evidence
|
||||||
|
and not has_clickup_evidence
|
||||||
|
):
|
||||||
|
return f"Manual upload PDF content found: {MANUAL_UPLOAD_PDF_CANARY_TOKEN}"
|
||||||
|
if (
|
||||||
|
has_manual_upload_md_evidence
|
||||||
|
and not has_confluence_evidence
|
||||||
|
and not has_jira_evidence
|
||||||
|
and not has_linear_evidence
|
||||||
|
and not has_notion_evidence
|
||||||
|
and not has_calendar_evidence
|
||||||
|
and not has_gmail_evidence
|
||||||
|
and not has_drive_evidence
|
||||||
|
and not has_onedrive_evidence
|
||||||
|
and not has_dropbox_evidence
|
||||||
|
and not has_slack_evidence
|
||||||
|
and not has_clickup_evidence
|
||||||
|
):
|
||||||
|
return f"Manual upload MD content found: {MANUAL_UPLOAD_MD_CANARY_TOKEN}"
|
||||||
return NO_RELEVANT_CONTENT_SENTINEL
|
return NO_RELEVANT_CONTENT_SENTINEL
|
||||||
|
|
||||||
def _tool_call_message_for(self, messages: list[BaseMessage]) -> AIMessage | None:
|
def _tool_call_message_for(self, messages: list[BaseMessage]) -> AIMessage | None:
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,7 @@ logging.basicConfig(
|
||||||
)
|
)
|
||||||
logger = logging.getLogger("surfsense.e2e.backend")
|
logger = logging.getLogger("surfsense.e2e.backend")
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"*** SURFSENSE E2E BACKEND ENTRYPOINT — fake Composio + LLM + embeddings, "
|
"*** SURFSENSE E2E BACKEND ENTRYPOINT — fake Composio + LLM + embeddings ***"
|
||||||
"this MUST NOT be reachable in production. ***"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,7 @@ logging.basicConfig(
|
||||||
)
|
)
|
||||||
logger = logging.getLogger("surfsense.e2e.celery")
|
logger = logging.getLogger("surfsense.e2e.celery")
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"*** SURFSENSE E2E CELERY WORKER — fake Composio + LLM + embeddings, "
|
"*** SURFSENSE E2E CELERY WORKER — fake Composio + LLM + embeddings ***"
|
||||||
"this MUST NOT be reachable in production. ***"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import type { APIRequestContext, Page } from "@playwright/test";
|
import type { APIRequestContext, Page } from "@playwright/test";
|
||||||
import { expect, test } from "../../fixtures";
|
import { expect, manualUploadWithChatTest as test } from "../../fixtures";
|
||||||
|
import type { ChatThreadRow } from "../../fixtures/chat-thread.fixture";
|
||||||
|
import { streamChatToCompletion } from "../../helpers/api/chat";
|
||||||
import { getEditorContent, listDocuments } from "../../helpers/api/documents";
|
import { getEditorContent, listDocuments } from "../../helpers/api/documents";
|
||||||
import { CANARY_TOKENS } from "../../helpers/canary";
|
import { CANARY_TOKENS } from "../../helpers/canary";
|
||||||
import { waitForDocumentByTitle } from "../../helpers/waits/indexing";
|
import { waitForDocumentByTitle } from "../../helpers/waits/indexing";
|
||||||
|
|
@ -9,6 +11,7 @@ type UploadFixture = {
|
||||||
path: string;
|
path: string;
|
||||||
name: string;
|
name: string;
|
||||||
canary: string;
|
canary: string;
|
||||||
|
chatQuery: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SearchSpace = {
|
type SearchSpace = {
|
||||||
|
|
@ -19,12 +22,14 @@ const MD_FILE: UploadFixture = {
|
||||||
path: path.join(__dirname, "fixtures", "canary.md"),
|
path: path.join(__dirname, "fixtures", "canary.md"),
|
||||||
name: "canary.md",
|
name: "canary.md",
|
||||||
canary: CANARY_TOKENS.manualUploadMdCanary,
|
canary: CANARY_TOKENS.manualUploadMdCanary,
|
||||||
|
chatQuery: "What is in my uploaded canary.md markdown file?",
|
||||||
};
|
};
|
||||||
|
|
||||||
const PDF_FILE: UploadFixture = {
|
const PDF_FILE: UploadFixture = {
|
||||||
path: path.join(__dirname, "fixtures", "canary.pdf"),
|
path: path.join(__dirname, "fixtures", "canary.pdf"),
|
||||||
name: "canary.pdf",
|
name: "canary.pdf",
|
||||||
canary: CANARY_TOKENS.manualUploadPdfCanary,
|
canary: CANARY_TOKENS.manualUploadPdfCanary,
|
||||||
|
chatQuery: "What is in my uploaded canary.pdf file?",
|
||||||
};
|
};
|
||||||
|
|
||||||
async function uploadAndAssert({
|
async function uploadAndAssert({
|
||||||
|
|
@ -32,12 +37,14 @@ async function uploadAndAssert({
|
||||||
request,
|
request,
|
||||||
apiToken,
|
apiToken,
|
||||||
searchSpace,
|
searchSpace,
|
||||||
|
chatThread,
|
||||||
file,
|
file,
|
||||||
}: {
|
}: {
|
||||||
page: Page;
|
page: Page;
|
||||||
request: APIRequestContext;
|
request: APIRequestContext;
|
||||||
apiToken: string;
|
apiToken: string;
|
||||||
searchSpace: SearchSpace;
|
searchSpace: SearchSpace;
|
||||||
|
chatThread: ChatThreadRow;
|
||||||
file: UploadFixture;
|
file: UploadFixture;
|
||||||
}) {
|
}) {
|
||||||
await page.goto(`/dashboard/${searchSpace.id}/new-chat`, {
|
await page.goto(`/dashboard/${searchSpace.id}/new-chat`, {
|
||||||
|
|
@ -68,6 +75,16 @@ async function uploadAndAssert({
|
||||||
const editor = await getEditorContent(request, apiToken, searchSpace.id, uploaded.id);
|
const editor = await getEditorContent(request, apiToken, searchSpace.id, uploaded.id);
|
||||||
expect(editor.source_markdown).toContain(file.canary);
|
expect(editor.source_markdown).toContain(file.canary);
|
||||||
expect(editor.chunk_count).toBeGreaterThan(0);
|
expect(editor.chunk_count).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
const chat = await streamChatToCompletion(request, apiToken, {
|
||||||
|
searchSpaceId: searchSpace.id,
|
||||||
|
threadId: chatThread.id,
|
||||||
|
query: file.chatQuery,
|
||||||
|
});
|
||||||
|
expect(
|
||||||
|
chat.assistantText,
|
||||||
|
`chat agent should surface manual upload canary after indexing; got: ${chat.assistantText.slice(0, 200)}`
|
||||||
|
).toContain(file.canary);
|
||||||
}
|
}
|
||||||
|
|
||||||
test.describe("Manual file upload journey", () => {
|
test.describe("Manual file upload journey", () => {
|
||||||
|
|
@ -76,10 +93,18 @@ test.describe("Manual file upload journey", () => {
|
||||||
request,
|
request,
|
||||||
apiToken,
|
apiToken,
|
||||||
searchSpace,
|
searchSpace,
|
||||||
|
chatThread,
|
||||||
}) => {
|
}) => {
|
||||||
test.setTimeout(180_000);
|
test.setTimeout(180_000);
|
||||||
|
|
||||||
await uploadAndAssert({ page, request, apiToken, searchSpace, file: MD_FILE });
|
await uploadAndAssert({
|
||||||
|
page,
|
||||||
|
request,
|
||||||
|
apiToken,
|
||||||
|
searchSpace,
|
||||||
|
chatThread,
|
||||||
|
file: MD_FILE,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("user uploads a PDF (DOCUMENT branch via real Docling)", async ({
|
test("user uploads a PDF (DOCUMENT branch via real Docling)", async ({
|
||||||
|
|
@ -87,9 +112,17 @@ test.describe("Manual file upload journey", () => {
|
||||||
request,
|
request,
|
||||||
apiToken,
|
apiToken,
|
||||||
searchSpace,
|
searchSpace,
|
||||||
|
chatThread,
|
||||||
}) => {
|
}) => {
|
||||||
test.setTimeout(240_000); // Docling cold-start can take 30-60s on first invocation.
|
test.setTimeout(240_000); // Docling cold-start can take 30-60s on first invocation.
|
||||||
|
|
||||||
await uploadAndAssert({ page, request, apiToken, searchSpace, file: PDF_FILE });
|
await uploadAndAssert({
|
||||||
|
page,
|
||||||
|
request,
|
||||||
|
apiToken,
|
||||||
|
searchSpace,
|
||||||
|
chatThread,
|
||||||
|
file: PDF_FILE,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
9
surfsense_web/tests/fixtures/index.ts
vendored
9
surfsense_web/tests/fixtures/index.ts
vendored
|
|
@ -36,6 +36,7 @@
|
||||||
* └─ clickupWithChatTest — chatThread
|
* └─ clickupWithChatTest — chatThread
|
||||||
* └─ slackFixtures — slackConnector
|
* └─ slackFixtures — slackConnector
|
||||||
* └─ slackWithChatTest — chatThread
|
* └─ slackWithChatTest — chatThread
|
||||||
|
* └─ manualUploadWithChatTest — chatThread (no connector; uses base search space)
|
||||||
*
|
*
|
||||||
* To add a new connector (Gmail, Slack, manual upload, etc.):
|
* To add a new connector (Gmail, Slack, manual upload, etc.):
|
||||||
* 1. Add a fixture file under `fixtures/connectors/<name>.fixture.ts`.
|
* 1. Add a fixture file under `fixtures/connectors/<name>.fixture.ts`.
|
||||||
|
|
@ -144,3 +145,11 @@ export const clickupWithChatTest = clickupFixtures.extend<ChatThreadFixtures>(ch
|
||||||
export const slackTest = slackFixtures;
|
export const slackTest = slackFixtures;
|
||||||
/** `test` for Slack specs that also need a chat thread. */
|
/** `test` for Slack specs that also need a chat thread. */
|
||||||
export const slackWithChatTest = slackFixtures.extend<ChatThreadFixtures>(chatThreadFixtures);
|
export const slackWithChatTest = slackFixtures.extend<ChatThreadFixtures>(chatThreadFixtures);
|
||||||
|
/**
|
||||||
|
* `test` for manual upload specs that also need a chat thread.
|
||||||
|
*
|
||||||
|
* Manual upload has no connector fixture — the user uploads files directly via
|
||||||
|
* the Documents-sidebar UI — so this composes chat onto the bare search-space.
|
||||||
|
*/
|
||||||
|
export const manualUploadWithChatTest =
|
||||||
|
searchSpaceFixtures.extend<ChatThreadFixtures>(chatThreadFixtures);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue