openxiangda-cli 2.0.0-alpha.170 → 2.0.0-alpha.171
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openxiangda-cli",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.171",
|
|
4
4
|
"description": "Thin application-level CLI for OpenXiangda 2.0.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@oclif/core": "4.13.3",
|
|
24
24
|
"openxiangda-contracts": "2.0.0-alpha.85",
|
|
25
|
-
"openxiangda-devkit-core": "2.0.0-alpha.
|
|
26
|
-
"openxiangda-mcp": "2.0.0-alpha.
|
|
27
|
-
"openxiangda-skill-kit": "2.0.0-alpha.
|
|
25
|
+
"openxiangda-devkit-core": "2.0.0-alpha.109",
|
|
26
|
+
"openxiangda-mcp": "2.0.0-alpha.109",
|
|
27
|
+
"openxiangda-skill-kit": "2.0.0-alpha.134"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"tsx": "4.23.12",
|
|
@@ -24,6 +24,7 @@ const runtimeBase = `/view/${appCode}`;
|
|
|
24
24
|
|
|
25
25
|
const semanticResourceItem = {
|
|
26
26
|
id: 'group-1',
|
|
27
|
+
name: '组织信息演示',
|
|
27
28
|
revision: 1,
|
|
28
29
|
updated_at: '2026-08-28T01:00:00.000Z',
|
|
29
30
|
departmentMultiple: [
|
|
@@ -304,6 +305,9 @@ test('renders canonical semantic labels in the real generated resource list', as
|
|
|
304
305
|
await mockPlatform(page, true, runtimeBase, true, {
|
|
305
306
|
[resourceCode]: [semanticResourceItem],
|
|
306
307
|
});
|
|
308
|
+
await page.route('**/native/data/resource-01/records/group-1?*', async route => {
|
|
309
|
+
await route.fulfill({ json: { code: 200, data: { schemaVersion: 'openxiangda.data-record/v2', data: semanticResourceItem } } });
|
|
310
|
+
});
|
|
307
311
|
await page.goto('/resource-experience.e2e.html');
|
|
308
312
|
await expect(page).toHaveURL(`/admin/resources/${resourceCode}`);
|
|
309
313
|
const row = page.getByRole('row').filter({ hasText: '信息技术部' });
|
|
@@ -327,7 +331,11 @@ test('renders canonical semantic labels in the real generated resource list', as
|
|
|
327
331
|
path: 'test-results/generated-resource-semantic-values-desktop.png',
|
|
328
332
|
});
|
|
329
333
|
await row.getByText('信息技术部', { exact: true }).click();
|
|
330
|
-
await expect(page).toHaveURL(`/admin/resources/${resourceCode}
|
|
334
|
+
await expect(page).toHaveURL(`/admin/resources/${resourceCode}`);
|
|
335
|
+
const detail = page.getByRole('dialog');
|
|
336
|
+
await expect(detail).toBeVisible();
|
|
337
|
+
await expect(detail).toContainText('组织信息演示');
|
|
338
|
+
await expect(detail.locator('.oxa-form-section')).toHaveCount(2);
|
|
331
339
|
});
|
|
332
340
|
|
|
333
341
|
test('renders the canonical first field on the mobile generated list', async ({ page }) => {
|
|
@@ -255,7 +255,7 @@ test('grouped drawer validates, preserves input after failure and refreshes the
|
|
|
255
255
|
expect(errors).toEqual([]);
|
|
256
256
|
});
|
|
257
257
|
|
|
258
|
-
test('drawer full screen preserves input, close
|
|
258
|
+
test('drawer full screen preserves input, close discards edits and new page restores a saved draft', async ({ page }, testInfo) => {
|
|
259
259
|
const state = await editablePlatform(page);
|
|
260
260
|
await page.goto('/resource-experience.e2e.html?primary=business');
|
|
261
261
|
await page.getByRole('button', { name: '新增', exact: true }).click();
|
|
@@ -269,13 +269,16 @@ test('drawer full screen preserves input, close protects edits and new page rest
|
|
|
269
269
|
await expect.poll(async () => (await drawer.boundingBox())!.width).toBe(page.viewportSize()!.width);
|
|
270
270
|
await drawer.getByRole('button', { name: '退出全屏', exact: true }).click();
|
|
271
271
|
await drawer.getByRole('button', { name: '关闭', exact: true }).click();
|
|
272
|
-
await
|
|
273
|
-
await expect(
|
|
272
|
+
await expect(drawer).toBeHidden();
|
|
273
|
+
await expect(page.getByRole('button', { name: '继续填写' })).toHaveCount(0);
|
|
274
|
+
await page.getByRole('button', { name: '新增', exact: true }).click();
|
|
275
|
+
await drawer.getByLabel('栏目名称', { exact: true }).fill('新页面继续填写');
|
|
274
276
|
const opened = page.context().waitForEvent('page');
|
|
275
277
|
await drawer.getByRole('button', { name: '新开页面' }).click();
|
|
276
278
|
const nextPage = await opened;
|
|
277
279
|
await expect(nextPage).toHaveURL(/\/admin\/resources\/resource-01\/new\?draft=/);
|
|
278
|
-
await expect(nextPage.locator('.oxa-topbar')).
|
|
280
|
+
await expect(nextPage.locator('.oxa-topbar, .oxa-sider')).toHaveCount(0);
|
|
281
|
+
await expect(nextPage.locator('.oxa-independent-form-header')).toContainText('内容栏目');
|
|
279
282
|
await expect(nextPage.getByLabel('栏目名称', { exact: true })).toHaveValue('新页面继续填写');
|
|
280
283
|
await expect(drawer).toBeHidden();
|
|
281
284
|
expect(state.writes).toHaveLength(0);
|
|
@@ -439,3 +442,42 @@ test('mobile partial drafts restore from a bottom sheet and submit once', async
|
|
|
439
442
|
await expect(page).toHaveURL('/m/admin/resources/resource-01');
|
|
440
443
|
expect(state.writes).toHaveLength(1); expect(state.drafts).toHaveLength(0);
|
|
441
444
|
});
|
|
445
|
+
|
|
446
|
+
test('direct entry is independent and adapts desktop URLs to touch controls without losing values', async ({ page }) => {
|
|
447
|
+
await editablePlatform(page);
|
|
448
|
+
await page.goto('/admin/resources/resource-01/new');
|
|
449
|
+
await expect(page.locator('.oxa-sider, .oxa-topbar')).toHaveCount(0);
|
|
450
|
+
await expect(page.getByRole('button', { name: '返回列表' })).toHaveCount(0);
|
|
451
|
+
await page.getByRole('textbox', { name: /栏目名称/ }).fill('保留未暂存输入');
|
|
452
|
+
await page.setViewportSize({ width: 390, height: 844 });
|
|
453
|
+
await expect(page.locator('.oxa-mobile-form')).toBeVisible();
|
|
454
|
+
await expect(page.locator('.oxa-mobile-entry')).toBeVisible();
|
|
455
|
+
await expect(page.getByRole('textbox', { name: /栏目名称/ })).toHaveValue('保留未暂存输入');
|
|
456
|
+
await expect(page.locator('.oxa-sider, .oxa-topbar')).toHaveCount(0);
|
|
457
|
+
await page.setViewportSize({ width: 1280, height: 900 });
|
|
458
|
+
await expect(page.locator('.oxa-form-full')).toBeVisible();
|
|
459
|
+
await expect(page.getByRole('textbox', { name: /栏目名称/ })).toHaveValue('保留未暂存输入');
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
test('details open readonly in a drawer and closing unsaved entry has no confirmation or write', async ({ page }) => {
|
|
463
|
+
const state = await editablePlatform(page);
|
|
464
|
+
await page.goto('/resource-experience.e2e.html?primary=business');
|
|
465
|
+
const initialUrl = page.url();
|
|
466
|
+
await page.getByRole('button', { name: '查看', exact: true }).first().click();
|
|
467
|
+
const detail = page.getByRole('dialog', { name: '内容栏目详情' });
|
|
468
|
+
await expect(detail).toBeVisible();
|
|
469
|
+
await expect(detail.locator('.oxa-form-sections')).toBeVisible();
|
|
470
|
+
await expect(detail.getByText('业务记录 1', { exact: true })).toBeVisible();
|
|
471
|
+
await expect(detail.getByRole('textbox')).toHaveCount(0);
|
|
472
|
+
await expect(detail.getByRole('button', { name: '提交', exact: true })).toHaveCount(0);
|
|
473
|
+
expect(page.url()).toBe(initialUrl);
|
|
474
|
+
await detail.getByRole('button', { name: '关闭', exact: true }).click();
|
|
475
|
+
await page.getByRole('button', { name: '新增', exact: true }).click();
|
|
476
|
+
const entry = page.getByRole('dialog', { name: '新增数据' });
|
|
477
|
+
await entry.getByRole('textbox', { name: /栏目名称/ }).fill('不保存的输入');
|
|
478
|
+
await entry.getByRole('button', { name: '关闭', exact: true }).click();
|
|
479
|
+
await expect(entry).toHaveCount(0);
|
|
480
|
+
await expect(page.getByText('放弃未暂存的修改?', { exact: true })).toHaveCount(0);
|
|
481
|
+
expect(state.writes).toHaveLength(0);
|
|
482
|
+
expect(state.draftWrites).toHaveLength(0);
|
|
483
|
+
});
|