Skip to content

Commit 971f7b9

Browse files
test(e2e): replace Chinese comment with English in error-messages suite
The CJK path fixture used a Chinese comment '文档' (document). Replace with English equivalent to comply with codebase English-only policy.
1 parent 33af0f5 commit 971f7b9

3 files changed

Lines changed: 81 additions & 39 deletions

File tree

‎cli/test/e2e/.env.e2e.example‎

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,63 @@
1-
# E2E test environment template — copy to .env.e2e and fill in the values.
1+
# E2E test environment template — copy to ../.env.e2e or cli/.env.e2e
2+
# depending on the test command working directory, then fill in values.
3+
#
24
# .env.e2e is git-ignored; this file is safe to commit.
35
#
6+
# ── Run mode ────────────────────────────────────────────────────────────────
7+
# Leave unset for real staging E2E. Set to "local" only for local-mode suites.
8+
# DIFY_E2E_MODE=local
9+
410
# ── Edition selector ────────────────────────────────────────────────────────
5-
# "ce" (default) = Community Edition "ee" = Enterprise Edition
6-
# EE-only test cases ([EE] tag) are automatically skipped in CE mode.
7-
DIFY_E2E_EDITION=ce
11+
# ce = Community Edition (default)
12+
# ee = Enterprise Edition; requires workspaces named exactly auto_test0/auto_test1.
13+
DIFY_E2E_EDITION=ee
814

9-
# ── Required (both editions) ────────────────────────────────────────────────
15+
# ── Required for real staging E2E ───────────────────────────────────────────
16+
# DIFY_E2E_HOST is the OpenAPI / console base URL unless DIFY_E2E_CONSOLE_URL is set.
1017
DIFY_E2E_HOST=
1118
DIFY_E2E_EMAIL=
1219
DIFY_E2E_PASSWORD=
1320

14-
# ── EE notes ────────────────────────────────────────────────────────────────
15-
# When DIFY_E2E_EDITION=ee the operator must pre-create two workspaces for the
16-
# test account BEFORE running the suite:
17-
# primary → workspace name: "auto_test0"
18-
# secondary → workspace name: "auto_test1"
19-
# global-setup discovers them by exact name, imports DSL fixtures into both,
20-
# publishes apps, and sets access_mode → public automatically.
21+
# ── Enterprise workspace contract ───────────────────────────────────────────
22+
# For DIFY_E2E_EDITION=ee, the logged-in account must already have:
23+
# auto_test0 → primary workspace; global-setup checks 8 fixture apps here.
24+
# auto_test1 → secondary workspace; global-setup checks 1 fixture app here.
25+
#
26+
# If either workspace is missing, global-setup does not import DSL fixtures.
27+
# If a fixture app is missing, global-setup imports it from test/e2e/fixtures/apps.
28+
# If it already exists by exact app name, import is skipped.
29+
#
30+
# auto_test0 fixture apps:
31+
# echo-chat.yml → echo-bot
32+
# echo-workflow.yml → basic_auto_test
33+
# file-upload.yml → file_auto_test
34+
# hitl-main.yml → hitl_auto_test
35+
# hitl-external.yml → DIFY_E2E_HITL_EXTERNAL
36+
# hitl-single-action.yml → DIFY_E2E_HITL_SINGLE_ACTION
37+
# hitl-multi-node.yml → DIFY_E2E_HITL_MULTI_NODE
38+
# file-chat.yml → DIFY_E2E_FILE_CHAT
39+
#
40+
# auto_test1 fixture app:
41+
# ws2-workflow.yml → auto_test_workspace2
2142

22-
# ── Optional overrides ───────────────────────────────────────────────────────
23-
# Console URL when different from DIFY_E2E_HOST (e.g. EE console proxy)
43+
# ── Optional host override ──────────────────────────────────────────────────
44+
# Use only when console login/provisioning URL differs from DIFY_E2E_HOST.
2445
# DIFY_E2E_CONSOLE_URL=
2546

26-
# Pre-minted primary token — skips device-flow mint in global-setup
47+
# ── Optional tokens ─────────────────────────────────────────────────────────
48+
# Primary internal bearer token (dfoa_). When unset, global-setup mints/caches one.
2749
# DIFY_E2E_TOKEN=
28-
29-
# External SSO bearer token (dfoe_ prefix) — enables SSO test cases
50+
#
51+
# External SSO bearer token (dfoe_). Required only for SSO-specific cases.
3052
# DIFY_E2E_SSO_TOKEN=
3153

32-
# Override workspace IDs (default: discovered by global-setup)
54+
# ── Optional manual fallbacks ────────────────────────────────────────────────
55+
# Normally leave these blank: global-setup discovers workspaces and fixture app IDs.
56+
# They are fallback values for debugging or when provisioning is intentionally skipped.
3357
# DIFY_E2E_WORKSPACE_ID=
34-
# DIFY_E2E_WORKSPACE_NAME=
58+
# DIFY_E2E_WORKSPACE_NAME=auto_test0
3559
# DIFY_E2E_WS2_ID=
36-
37-
# Override app IDs (default: provisioned from fixture DSL files)
60+
#
3861
# DIFY_E2E_CHAT_APP_ID=
3962
# DIFY_E2E_WORKFLOW_APP_ID=
4063
# DIFY_E2E_FILE_APP_ID=

‎cli/test/e2e/setup/global-setup.ts‎

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,36 @@ export async function setup(project: TestProject): Promise<void> {
157157
}
158158

159159
// ── Discover workspaces ──────────────────────────────────────────────────
160-
const { primaryWsId, primaryWsName, secondaryWsId } = await discoverWorkspaces(
160+
const workspaces = await discoverWorkspaces(
161161
consoleBase,
162162
cookieString,
163163
csrfToken,
164164
E.edition,
165165
)
166+
if (!workspaces) {
167+
project.provide('e2eCapabilities', {
168+
tokenValid: true,
169+
tokenId: match?.id,
170+
edition: E.edition,
171+
token: primaryToken,
172+
logoutToken: '',
173+
devicesToken: '',
174+
workspaceId: '',
175+
workspaceName: '',
176+
ws2Id: '',
177+
chatAppId: '',
178+
workflowAppId: '',
179+
fileAppId: '',
180+
fileChatAppId: '',
181+
hitlAppId: '',
182+
hitlExternalAppId: '',
183+
hitlSingleActionAppId: '',
184+
hitlMultiNodeAppId: '',
185+
ws2AppId: '',
186+
} satisfies E2ECapabilities)
187+
return
188+
}
189+
const { primaryWsId, primaryWsName, secondaryWsId } = workspaces
166190

167191
// ── Mint per-suite dedicated tokens ──────────────────────────────────────
168192
let logoutToken = ''
@@ -325,7 +349,7 @@ async function discoverWorkspaces(
325349
cookieString: string,
326350
csrfToken: string,
327351
edition: 'ce' | 'ee',
328-
): Promise<{ primaryWsId: string, primaryWsName: string, secondaryWsId: string }> {
352+
): Promise<{ primaryWsId: string, primaryWsName: string, secondaryWsId: string } | null> {
329353
const wsRes = await fetch(`${consoleBase}/console/api/workspaces`, {
330354
headers: { 'Cookie': cookieString, 'X-CSRF-Token': csrfToken },
331355
signal: AbortSignal.timeout(10_000),
@@ -343,26 +367,21 @@ async function discoverWorkspaces(
343367
const ws0 = all.find(w => w.name === 'auto_test0')
344368
const ws1 = all.find(w => w.name === 'auto_test1')
345369

346-
if (!ws0) {
347-
throw new Error(
348-
'[E2E EE] Workspace "auto_test0" not found. '
349-
+ 'Please pre-create it for the test account before running E2E tests.',
350-
)
351-
}
352-
353-
if (!ws1) {
370+
if (!ws0 || !ws1) {
371+
const existing = all.map(w => w.name).join(', ') || '(none)'
354372
console.warn(
355-
'[E2E EE] Workspace "auto_test1" not found — secondary workspace will reuse primary. '
356-
+ 'Cross-workspace [EE] tests may not work correctly.',
373+
`[E2E EE] Required workspaces not found; expected auto_test0 and auto_test1, got: ${existing}. `
374+
+ 'Skip fixture app provisioning.',
357375
)
376+
return null
358377
}
359378

360379
const primaryWsId = ws0.id
361380
const primaryWsName = ws0.name
362-
const secondaryWsId = ws1?.id ?? ws0.id
381+
const secondaryWsId = ws1.id
363382

364383
console.warn(`[E2E EE] primary workspace: ${primaryWsName} (${primaryWsId})`)
365-
console.warn(`[E2E EE] secondary workspace: ${ws1?.name ?? 'reuses primary'} (${secondaryWsId})`)
384+
console.warn(`[E2E EE] secondary workspace: ${ws1.name} (${secondaryWsId})`)
366385

367386
return { primaryWsId, primaryWsName, secondaryWsId }
368387
}
@@ -460,7 +479,7 @@ async function provisionApps(
460479
const url = `${consoleBase}/console/api/apps?name=${encodeURIComponent(name)}&limit=50&page=1`
461480
const r = await fetch(url, { headers: mkHeaders(), signal: AbortSignal.timeout(10_000) })
462481
if (!r.ok)
463-
return null
482+
throw new Error(`list apps by name "${name}" failed: HTTP ${r.status}`)
464483
const d = await r.json() as { data?: Array<{ id: string, name: string }> }
465484
return d.data?.find(a => a.name === name)?.id ?? null
466485
}
@@ -540,14 +559,14 @@ async function provisionApps(
540559
}
541560

542561
const dsl = await readFile(join(fixturesDir, dslFile), 'utf8')
543-
const appName = (dsl.match(/^[ \t]+name:[ \t]*(\\S[^\\n]*)$/m) ?? [])[1]
562+
const appName = (dsl.match(/^[ \t]+name:[ \t]*(\S[^\n]*)$/m) ?? [])[1]
544563
?.trim()
545564
.replace(/^['"]|['"]$/g, '') ?? dslFile
546565
const appMode = (dsl.match(/^\s+mode:\s*(\S+)/m) ?? [])[1] ?? ''
547566

548567
let appId = await findAppByName(appName)
549568
if (appId) {
550-
console.warn(`[E2E provision] ${dslFile}: exists id=${appId}`)
569+
console.warn(`[E2E provision] ${dslFile}: exists in workspace id=${appId}; skip import`)
551570
}
552571
else {
553572
appId = await importFromDsl(dsl)

‎cli/test/e2e/suites/error-handling/error-messages.e2e.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ describe('E2E / error message standards (spec 5.3)', () => {
218218
// not exist, the error message must display the path without garbling.
219219
const fileDir = await mkdtemp(join(tmpdir(), 'difyctl-e2e-cjk-'))
220220
try {
221-
const cjkPath = join(fileDir, 'cjk-test-\u6587\u6863.txt') // "文档"
221+
const cjkPath = join(fileDir, 'cjk-test-\u6587\u6863.txt') // "document" in Chinese — tests CJK path handling
222222
// Do not create the file — we want the "not found" error
223223
const result = await fx.r([
224224
'run',

0 commit comments

Comments
 (0)