miaoda-game-devkit 0.2.16 → 0.2.17
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/README.md +11 -0
- package/dist/react/testing.d.mts +9 -0
- package/dist/react/testing.d.ts +9 -0
- package/dist/react/testing.js +27 -1
- package/dist/react/testing.mjs +17 -1
- package/dist/react/vitest-config.js +29 -2
- package/dist/react/vitest-config.mjs +19 -2
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -10,6 +10,17 @@
|
|
|
10
10
|
- React 的 `playthroughTest` 与项目级 reporter 自动验证生产入口、真实 DOM 输入、
|
|
11
11
|
有界推进和结果断言;聚焦运行只提示未检查,完整运行缺少有效流程时失败;
|
|
12
12
|
|
|
13
|
+
`playthroughTest` 的主流程回调从参数接收已配置好的 `user`,不要再调用
|
|
14
|
+
`userEvent.setup()`。这避免生成测试自行处理输入实例,但不会隐式接管全局 timer。
|
|
15
|
+
时间、帧或自定义 scheduler 流程必须显式传入确定性 `step`;精确物理时间、暂停恢复
|
|
16
|
+
或调度清理测试可使用 `ManualGameClock`。
|
|
17
|
+
|
|
18
|
+
Vitest 的 fake timers(包括 `vi.advanceTimersToNextFrame()`)适合在 devkit 自身的
|
|
19
|
+
专门 scheduler 合约中使用,但不在所有 production playthrough 中全局启用;React
|
|
20
|
+
Testing Library 的 `asyncWrapper` 和 user-event 内部 timer 会因此互相影响。使用自定义
|
|
21
|
+
scheduler、Worker 或未通过浏览器 timer 接入的引擎时,应传显式 `step` 并通过
|
|
22
|
+
`diagnostics` 暴露权威状态。
|
|
23
|
+
|
|
13
24
|
- React Vitest 在项目声明 Phaser 3 时使用其 browser bundle,并提供仅供模块能力探测的
|
|
14
25
|
最小 Canvas 2D 边界,使 Phaser 3 代码不会阻断普通 JSDOM 测试;Storage 使用 JSDOM
|
|
15
26
|
按 origin 提供的原生实现,Node 25+ worker 会关闭冲突的 Node Web Storage,
|
package/dist/react/testing.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { G as GameClock, a as GameFrameCallback } from '../game-clock-suUidZdT.mjs';
|
|
2
2
|
import { RenderResult } from '@testing-library/react';
|
|
3
|
+
import { UserEvent } from '@testing-library/user-event';
|
|
3
4
|
import { ReactNode } from 'react';
|
|
4
5
|
|
|
5
6
|
/** 测试用确定性时钟;应用测试推进它,不直接伪造游戏状态。 */
|
|
@@ -26,6 +27,11 @@ interface StepUntilOptions {
|
|
|
26
27
|
maxSteps?: number;
|
|
27
28
|
/** 每轮推进一单位游戏自有时间或工作;即时回合制结果可以省略。 */
|
|
28
29
|
step?: (step: number) => void | Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Optional read-only state used to make bounded failures actionable.
|
|
32
|
+
* The value is sampled only when the bound is exhausted.
|
|
33
|
+
*/
|
|
34
|
+
diagnostics?: () => unknown;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
/** 单条 React 主流程测试留下的可序列化运行期证据。 */
|
|
@@ -53,9 +59,12 @@ interface ReactPlaythroughMetadata {
|
|
|
53
59
|
interface ReactPlaythroughArguments {
|
|
54
60
|
/** Testing Library 对生产游戏入口的渲染结果。 */
|
|
55
61
|
view: RenderResult;
|
|
62
|
+
/** 已由 playthroughTest 创建的真实 DOM 用户输入驱动。 */
|
|
63
|
+
user: UserEvent;
|
|
56
64
|
/**
|
|
57
65
|
* 在硬性步数上限内等待权威结果。
|
|
58
66
|
* 返回后必须再断言该结果,进入中间 active/running 状态不算完成。
|
|
67
|
+
* 即时结果不需要 step;时间、帧或自定义 scheduler 流程必须传入确定性 step。
|
|
59
68
|
*/
|
|
60
69
|
stepUntil(condition: () => boolean, options?: StepUntilOptions): Promise<number>;
|
|
61
70
|
}
|
package/dist/react/testing.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { G as GameClock, a as GameFrameCallback } from '../game-clock-suUidZdT.js';
|
|
2
2
|
import { RenderResult } from '@testing-library/react';
|
|
3
|
+
import { UserEvent } from '@testing-library/user-event';
|
|
3
4
|
import { ReactNode } from 'react';
|
|
4
5
|
|
|
5
6
|
/** 测试用确定性时钟;应用测试推进它,不直接伪造游戏状态。 */
|
|
@@ -26,6 +27,11 @@ interface StepUntilOptions {
|
|
|
26
27
|
maxSteps?: number;
|
|
27
28
|
/** 每轮推进一单位游戏自有时间或工作;即时回合制结果可以省略。 */
|
|
28
29
|
step?: (step: number) => void | Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Optional read-only state used to make bounded failures actionable.
|
|
32
|
+
* The value is sampled only when the bound is exhausted.
|
|
33
|
+
*/
|
|
34
|
+
diagnostics?: () => unknown;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
/** 单条 React 主流程测试留下的可序列化运行期证据。 */
|
|
@@ -53,9 +59,12 @@ interface ReactPlaythroughMetadata {
|
|
|
53
59
|
interface ReactPlaythroughArguments {
|
|
54
60
|
/** Testing Library 对生产游戏入口的渲染结果。 */
|
|
55
61
|
view: RenderResult;
|
|
62
|
+
/** 已由 playthroughTest 创建的真实 DOM 用户输入驱动。 */
|
|
63
|
+
user: UserEvent;
|
|
56
64
|
/**
|
|
57
65
|
* 在硬性步数上限内等待权威结果。
|
|
58
66
|
* 返回后必须再断言该结果,进入中间 active/running 状态不算完成。
|
|
67
|
+
* 即时结果不需要 step;时间、帧或自定义 scheduler 流程必须传入确定性 step。
|
|
59
68
|
*/
|
|
60
69
|
stepUntil(condition: () => boolean, options?: StepUntilOptions): Promise<number>;
|
|
61
70
|
}
|
package/dist/react/testing.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/react/testing.ts
|
|
@@ -83,10 +93,21 @@ var ManualGameClock = class {
|
|
|
83
93
|
|
|
84
94
|
// src/react/react-playthrough.ts
|
|
85
95
|
var import_react2 = require("@testing-library/react");
|
|
96
|
+
var import_user_event = __toESM(require("@testing-library/user-event"));
|
|
86
97
|
var import_vitest = require("vitest");
|
|
87
98
|
|
|
88
99
|
// src/react/react-playthrough-core.ts
|
|
89
100
|
var import_react = require("@testing-library/react");
|
|
101
|
+
function formatDiagnostics(read) {
|
|
102
|
+
if (!read) return void 0;
|
|
103
|
+
try {
|
|
104
|
+
const value = read();
|
|
105
|
+
if (typeof value === "string") return value;
|
|
106
|
+
return JSON.stringify(value);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return `diagnostics() threw: ${String(error)}`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
90
111
|
function normalizePlaythroughWaiverReason(waiverReason) {
|
|
91
112
|
if (waiverReason === void 0) return void 0;
|
|
92
113
|
const reason = waiverReason.trim();
|
|
@@ -112,8 +133,11 @@ async function runBoundedUntil(condition, options = {}) {
|
|
|
112
133
|
});
|
|
113
134
|
}
|
|
114
135
|
}
|
|
136
|
+
const diagnostics = formatDiagnostics(options.diagnostics);
|
|
137
|
+
const guidance = options.step ? "The step callback ran, but the authoritative outcome did not change." : "No step callback was provided, so time-driven gameplay was not advanced. Inject a ManualGameClock for this test and pass step: () => clock.stepFrame().";
|
|
138
|
+
const suffix = diagnostics ? ` Last diagnostics: ${diagnostics}` : "";
|
|
115
139
|
throw new Error(
|
|
116
|
-
`Playthrough outcome was not reached within ${maxSteps} steps
|
|
140
|
+
`Playthrough outcome was not reached within ${maxSteps} steps. ${guidance}${suffix}`
|
|
117
141
|
);
|
|
118
142
|
}
|
|
119
143
|
|
|
@@ -161,8 +185,10 @@ function definePlaythrough(element, run, waiverReason) {
|
|
|
161
185
|
"playthroughTest must render the production game entry."
|
|
162
186
|
);
|
|
163
187
|
}
|
|
188
|
+
const user = import_user_event.default.setup();
|
|
164
189
|
await run({
|
|
165
190
|
view,
|
|
191
|
+
user,
|
|
166
192
|
async stepUntil(condition, options = {}) {
|
|
167
193
|
const steps = await runBoundedUntil(condition, options);
|
|
168
194
|
if (evidence.domInputEvents === 0) {
|
package/dist/react/testing.mjs
CHANGED
|
@@ -55,10 +55,21 @@ var ManualGameClock = class {
|
|
|
55
55
|
|
|
56
56
|
// src/react/react-playthrough.ts
|
|
57
57
|
import { render } from "@testing-library/react";
|
|
58
|
+
import userEvent from "@testing-library/user-event";
|
|
58
59
|
import { expect, test } from "vitest";
|
|
59
60
|
|
|
60
61
|
// src/react/react-playthrough-core.ts
|
|
61
62
|
import { act } from "@testing-library/react";
|
|
63
|
+
function formatDiagnostics(read) {
|
|
64
|
+
if (!read) return void 0;
|
|
65
|
+
try {
|
|
66
|
+
const value = read();
|
|
67
|
+
if (typeof value === "string") return value;
|
|
68
|
+
return JSON.stringify(value);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return `diagnostics() threw: ${String(error)}`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
62
73
|
function normalizePlaythroughWaiverReason(waiverReason) {
|
|
63
74
|
if (waiverReason === void 0) return void 0;
|
|
64
75
|
const reason = waiverReason.trim();
|
|
@@ -84,8 +95,11 @@ async function runBoundedUntil(condition, options = {}) {
|
|
|
84
95
|
});
|
|
85
96
|
}
|
|
86
97
|
}
|
|
98
|
+
const diagnostics = formatDiagnostics(options.diagnostics);
|
|
99
|
+
const guidance = options.step ? "The step callback ran, but the authoritative outcome did not change." : "No step callback was provided, so time-driven gameplay was not advanced. Inject a ManualGameClock for this test and pass step: () => clock.stepFrame().";
|
|
100
|
+
const suffix = diagnostics ? ` Last diagnostics: ${diagnostics}` : "";
|
|
87
101
|
throw new Error(
|
|
88
|
-
`Playthrough outcome was not reached within ${maxSteps} steps
|
|
102
|
+
`Playthrough outcome was not reached within ${maxSteps} steps. ${guidance}${suffix}`
|
|
89
103
|
);
|
|
90
104
|
}
|
|
91
105
|
|
|
@@ -133,8 +147,10 @@ function definePlaythrough(element, run, waiverReason) {
|
|
|
133
147
|
"playthroughTest must render the production game entry."
|
|
134
148
|
);
|
|
135
149
|
}
|
|
150
|
+
const user = userEvent.setup();
|
|
136
151
|
await run({
|
|
137
152
|
view,
|
|
153
|
+
user,
|
|
138
154
|
async stepUntil(condition, options = {}) {
|
|
139
155
|
const steps = await runBoundedUntil(condition, options);
|
|
140
156
|
if (evidence.domInputEvents === 0) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/react-vitest-config.ts
|
|
@@ -33,10 +43,21 @@ var import_node_path = require("path");
|
|
|
33
43
|
|
|
34
44
|
// src/react/react-playthrough.ts
|
|
35
45
|
var import_react2 = require("@testing-library/react");
|
|
46
|
+
var import_user_event = __toESM(require("@testing-library/user-event"));
|
|
36
47
|
var import_vitest = require("vitest");
|
|
37
48
|
|
|
38
49
|
// src/react/react-playthrough-core.ts
|
|
39
50
|
var import_react = require("@testing-library/react");
|
|
51
|
+
function formatDiagnostics(read) {
|
|
52
|
+
if (!read) return void 0;
|
|
53
|
+
try {
|
|
54
|
+
const value = read();
|
|
55
|
+
if (typeof value === "string") return value;
|
|
56
|
+
return JSON.stringify(value);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return `diagnostics() threw: ${String(error)}`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
40
61
|
function normalizePlaythroughWaiverReason(waiverReason) {
|
|
41
62
|
if (waiverReason === void 0) return void 0;
|
|
42
63
|
const reason = waiverReason.trim();
|
|
@@ -62,8 +83,11 @@ async function runBoundedUntil(condition, options = {}) {
|
|
|
62
83
|
});
|
|
63
84
|
}
|
|
64
85
|
}
|
|
86
|
+
const diagnostics = formatDiagnostics(options.diagnostics);
|
|
87
|
+
const guidance = options.step ? "The step callback ran, but the authoritative outcome did not change." : "No step callback was provided, so time-driven gameplay was not advanced. Inject a ManualGameClock for this test and pass step: () => clock.stepFrame().";
|
|
88
|
+
const suffix = diagnostics ? ` Last diagnostics: ${diagnostics}` : "";
|
|
65
89
|
throw new Error(
|
|
66
|
-
`Playthrough outcome was not reached within ${maxSteps} steps
|
|
90
|
+
`Playthrough outcome was not reached within ${maxSteps} steps. ${guidance}${suffix}`
|
|
67
91
|
);
|
|
68
92
|
}
|
|
69
93
|
|
|
@@ -111,8 +135,10 @@ function definePlaythrough(element, run, waiverReason) {
|
|
|
111
135
|
"playthroughTest must render the production game entry."
|
|
112
136
|
);
|
|
113
137
|
}
|
|
138
|
+
const user = import_user_event.default.setup();
|
|
114
139
|
await run({
|
|
115
140
|
view,
|
|
141
|
+
user,
|
|
116
142
|
async stepUntil(condition, options = {}) {
|
|
117
143
|
const steps = await runBoundedUntil(condition, options);
|
|
118
144
|
if (evidence.domInputEvents === 0) {
|
|
@@ -273,11 +299,12 @@ function assessReactPlaythroughReport(input) {
|
|
|
273
299
|
if (!audit.passed) {
|
|
274
300
|
const cause = productionModule.errors[0] ?? input.unhandledErrors?.[0] ?? audit.issues[0] ?? "\u751F\u4EA7\u53EF\u73A9\u6D41\u7A0B\u6CA1\u6709\u7559\u4E0B\u5B8C\u6574\u8BC1\u636E\u3002";
|
|
275
301
|
const timedOut = /outcome was not reached within \d+ steps/i.test(cause);
|
|
302
|
+
const missingStep = /No step callback was provided/i.test(cause);
|
|
276
303
|
return {
|
|
277
304
|
...base,
|
|
278
305
|
status: "FAILED",
|
|
279
306
|
cause,
|
|
280
|
-
next: timedOut ? "\u771F\u5B9E\u8F93\u5165\u5DF2\u6267\u884C\uFF0C\u4F46\u73A9\u6CD5\u6CA1\u6709\u5728\u4E0A\u9650\u5185\u4EA7\u751F\u7ED3\u679C\uFF1B\u68C0\u67E5\
|
|
307
|
+
next: missingStep ? "\u8BE5\u6D41\u7A0B\u662F\u65F6\u95F4\u6216\u5E27\u9A71\u52A8\u7684\uFF0C\u4F46 stepUntil \u6CA1\u6709\u63A8\u8FDB\u6E38\u620F\u65F6\u95F4\uFF1B\u4E3A\u751F\u4EA7\u6E38\u620F\u6CE8\u5165 devkit \u7684 GameClock\uFF0C\u5E76\u4F20\u5165 step: () => clock.stepFrame()\u3002\u4E0D\u8981\u7528\u771F\u5B9E setTimeout\u3002" : timedOut ? "\u771F\u5B9E\u8F93\u5165\u5DF2\u6267\u884C\uFF0C\u4F46\u73A9\u6CD5\u6CA1\u6709\u5728\u4E0A\u9650\u5185\u4EA7\u751F\u7ED3\u679C\uFF1B\u68C0\u67E5\u751F\u4EA7\u63A7\u5236\u662F\u5426\u6536\u5230\u8F93\u5165\uFF0C\u518D\u67E5\u770B\u8D85\u65F6\u9519\u8BEF\u4E2D\u7684 Last diagnostics \u5224\u65AD\u662F\u6E38\u620F\u5FAA\u73AF\u3001\u89C4\u5219\u72B6\u6001\u8FD8\u662F UI \u540C\u6B65\u672A\u63A8\u8FDB\u3002" : "\u4ECE\u751F\u4EA7\u5165\u53E3\u6267\u884C\u771F\u5B9E DOM \u8F93\u5165\uFF0C\u7528 stepUntil \u6709\u754C\u63A8\u8FDB\u5230\u73A9\u5BB6\u53EF\u89C1\u7ED3\u679C\u6216\u6E38\u620F\u771F\u5B9E\u72B6\u6001\u7684\u53EA\u8BFB snapshot\uFF0C\u5E76\u5728\u5176\u540E\u65AD\u8A00\uFF1B\u4E0D\u8981\u76F4\u8FBE\u5185\u90E8\u5173\u5361\u6216\u4FEE\u6539\u73A9\u6CD5\u72B6\u6001\u3002",
|
|
281
308
|
failsRun: true
|
|
282
309
|
};
|
|
283
310
|
}
|
|
@@ -9,10 +9,21 @@ import { relative, resolve } from "path";
|
|
|
9
9
|
|
|
10
10
|
// src/react/react-playthrough.ts
|
|
11
11
|
import { render } from "@testing-library/react";
|
|
12
|
+
import userEvent from "@testing-library/user-event";
|
|
12
13
|
import { expect, test } from "vitest";
|
|
13
14
|
|
|
14
15
|
// src/react/react-playthrough-core.ts
|
|
15
16
|
import { act } from "@testing-library/react";
|
|
17
|
+
function formatDiagnostics(read) {
|
|
18
|
+
if (!read) return void 0;
|
|
19
|
+
try {
|
|
20
|
+
const value = read();
|
|
21
|
+
if (typeof value === "string") return value;
|
|
22
|
+
return JSON.stringify(value);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
return `diagnostics() threw: ${String(error)}`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
16
27
|
function normalizePlaythroughWaiverReason(waiverReason) {
|
|
17
28
|
if (waiverReason === void 0) return void 0;
|
|
18
29
|
const reason = waiverReason.trim();
|
|
@@ -38,8 +49,11 @@ async function runBoundedUntil(condition, options = {}) {
|
|
|
38
49
|
});
|
|
39
50
|
}
|
|
40
51
|
}
|
|
52
|
+
const diagnostics = formatDiagnostics(options.diagnostics);
|
|
53
|
+
const guidance = options.step ? "The step callback ran, but the authoritative outcome did not change." : "No step callback was provided, so time-driven gameplay was not advanced. Inject a ManualGameClock for this test and pass step: () => clock.stepFrame().";
|
|
54
|
+
const suffix = diagnostics ? ` Last diagnostics: ${diagnostics}` : "";
|
|
41
55
|
throw new Error(
|
|
42
|
-
`Playthrough outcome was not reached within ${maxSteps} steps
|
|
56
|
+
`Playthrough outcome was not reached within ${maxSteps} steps. ${guidance}${suffix}`
|
|
43
57
|
);
|
|
44
58
|
}
|
|
45
59
|
|
|
@@ -87,8 +101,10 @@ function definePlaythrough(element, run, waiverReason) {
|
|
|
87
101
|
"playthroughTest must render the production game entry."
|
|
88
102
|
);
|
|
89
103
|
}
|
|
104
|
+
const user = userEvent.setup();
|
|
90
105
|
await run({
|
|
91
106
|
view,
|
|
107
|
+
user,
|
|
92
108
|
async stepUntil(condition, options = {}) {
|
|
93
109
|
const steps = await runBoundedUntil(condition, options);
|
|
94
110
|
if (evidence.domInputEvents === 0) {
|
|
@@ -249,11 +265,12 @@ function assessReactPlaythroughReport(input) {
|
|
|
249
265
|
if (!audit.passed) {
|
|
250
266
|
const cause = productionModule.errors[0] ?? input.unhandledErrors?.[0] ?? audit.issues[0] ?? "\u751F\u4EA7\u53EF\u73A9\u6D41\u7A0B\u6CA1\u6709\u7559\u4E0B\u5B8C\u6574\u8BC1\u636E\u3002";
|
|
251
267
|
const timedOut = /outcome was not reached within \d+ steps/i.test(cause);
|
|
268
|
+
const missingStep = /No step callback was provided/i.test(cause);
|
|
252
269
|
return {
|
|
253
270
|
...base,
|
|
254
271
|
status: "FAILED",
|
|
255
272
|
cause,
|
|
256
|
-
next: timedOut ? "\u771F\u5B9E\u8F93\u5165\u5DF2\u6267\u884C\uFF0C\u4F46\u73A9\u6CD5\u6CA1\u6709\u5728\u4E0A\u9650\u5185\u4EA7\u751F\u7ED3\u679C\uFF1B\u68C0\u67E5\
|
|
273
|
+
next: missingStep ? "\u8BE5\u6D41\u7A0B\u662F\u65F6\u95F4\u6216\u5E27\u9A71\u52A8\u7684\uFF0C\u4F46 stepUntil \u6CA1\u6709\u63A8\u8FDB\u6E38\u620F\u65F6\u95F4\uFF1B\u4E3A\u751F\u4EA7\u6E38\u620F\u6CE8\u5165 devkit \u7684 GameClock\uFF0C\u5E76\u4F20\u5165 step: () => clock.stepFrame()\u3002\u4E0D\u8981\u7528\u771F\u5B9E setTimeout\u3002" : timedOut ? "\u771F\u5B9E\u8F93\u5165\u5DF2\u6267\u884C\uFF0C\u4F46\u73A9\u6CD5\u6CA1\u6709\u5728\u4E0A\u9650\u5185\u4EA7\u751F\u7ED3\u679C\uFF1B\u68C0\u67E5\u751F\u4EA7\u63A7\u5236\u662F\u5426\u6536\u5230\u8F93\u5165\uFF0C\u518D\u67E5\u770B\u8D85\u65F6\u9519\u8BEF\u4E2D\u7684 Last diagnostics \u5224\u65AD\u662F\u6E38\u620F\u5FAA\u73AF\u3001\u89C4\u5219\u72B6\u6001\u8FD8\u662F UI \u540C\u6B65\u672A\u63A8\u8FDB\u3002" : "\u4ECE\u751F\u4EA7\u5165\u53E3\u6267\u884C\u771F\u5B9E DOM \u8F93\u5165\uFF0C\u7528 stepUntil \u6709\u754C\u63A8\u8FDB\u5230\u73A9\u5BB6\u53EF\u89C1\u7ED3\u679C\u6216\u6E38\u620F\u771F\u5B9E\u72B6\u6001\u7684\u53EA\u8BFB snapshot\uFF0C\u5E76\u5728\u5176\u540E\u65AD\u8A00\uFF1B\u4E0D\u8981\u76F4\u8FBE\u5185\u90E8\u5173\u5361\u6216\u4FEE\u6539\u73A9\u6CD5\u72B6\u6001\u3002",
|
|
257
274
|
failsRun: true
|
|
258
275
|
};
|
|
259
276
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miaoda-game-devkit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"description": "Shared React and Phaser game lint plus deterministic testing tools for Miaoda games",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -126,6 +126,7 @@
|
|
|
126
126
|
"peerDependencies": {
|
|
127
127
|
"@testing-library/jest-dom": ">=6 <8",
|
|
128
128
|
"@testing-library/react": ">=16 <17",
|
|
129
|
+
"@testing-library/user-event": ">=14 <15",
|
|
129
130
|
"phaser": ">=4.0.0 <5",
|
|
130
131
|
"phaser4-rex-plugins": ">=4.0.0 <5",
|
|
131
132
|
"react": ">=19 <20",
|
|
@@ -139,6 +140,9 @@
|
|
|
139
140
|
"@testing-library/react": {
|
|
140
141
|
"optional": true
|
|
141
142
|
},
|
|
143
|
+
"@testing-library/user-event": {
|
|
144
|
+
"optional": true
|
|
145
|
+
},
|
|
142
146
|
"phaser": {
|
|
143
147
|
"optional": true
|
|
144
148
|
},
|