Download ComfyUI-MiniMaxH3-Context-Loop/tests/_chain_review_js_test.mjs from dzmdd/Fast_deploy: direct link, hf CLI and curl.
- Browser
- Download file 20.9 kB
-
https://huggingface.co/dzmdd/Fast_deploy/resolve/main/ComfyUI-MiniMaxH3-Context-Loop/tests/_chain_review_js_test.mjs
- Command line
-
hf download hf://dzmdd/Fast_deploy/ComfyUI-MiniMaxH3-Context-Loop/tests/_chain_review_js_test.mjs
-
curl -L -o _chain_review_js_test.mjs https://huggingface.co/dzmdd/Fast_deploy/resolve/main/ComfyUI-MiniMaxH3-Context-Loop/tests/_chain_review_js_test.mjs
20.9 kB
| import assert from "node:assert/strict"; | |
| import fs from "node:fs"; | |
| import { | |
| acceptedPreviewDisposition, | |
| applyCheckpointRevisionSeeds, | |
| applyCheckpointRevisionSet, | |
| applyReviewEdit, | |
| checkpointRevisionChain, | |
| checkpointResumeOptions, | |
| reviewCountdown, | |
| reviewDuration, | |
| reviewDurationText, | |
| reviewLocalDeadline, | |
| reviewPlanScenePrompt, | |
| reviewSeed, | |
| } from "../web/h3_chain_review_core.mjs"; | |
| const acceptedPin = { | |
| runName: "project", clipIndex: 5, token: "batch", revision: "a".repeat(32), | |
| }; | |
| assert.equal(acceptedPreviewDisposition(acceptedPin, { | |
| run_name: "project", clip_index: 4, token: "older", | |
| }), "ignore", "an earlier scene cannot replace an accepted preview"); | |
| assert.equal(acceptedPreviewDisposition(acceptedPin, { | |
| run_name: "project", clip_index: 5, token: "batch", | |
| }), "hold", "the accepted batch keeps its selected preview pinned"); | |
| assert.equal(acceptedPreviewDisposition(acceptedPin, { | |
| run_name: "project", clip_index: 5, token: "new-run", | |
| }), "release", "a new run of the same scene may replace the old preview"); | |
| assert.equal(acceptedPreviewDisposition(acceptedPin, { | |
| run_name: "project", clip_index: 6, token: "next", | |
| }), "release", "the next scene releases the accepted preview pin"); | |
| assert.equal(reviewSeed("18446744073709551615"), "18446744073709551615"); | |
| assert.throws(() => reviewSeed("18446744073709551616"), /uint64/); | |
| assert.deepEqual(reviewDuration("15"), {seconds: 15, length: 362}); | |
| assert.equal(reviewDurationText(362), "15.083333"); | |
| for (const length of [5, 22, 39, 56, 73, 362, 3592]) { | |
| assert.equal(reviewDuration(reviewDurationText(length)).length, length); | |
| } | |
| assert.throws(() => reviewDuration("0"), /positive/); | |
| assert.equal(reviewPlanScenePrompt({shots: [ | |
| {id: "one", prompt: ["First."]}, | |
| {id: "two", prompt: ["Second.", "", "CAMERA: Wide."]}, | |
| ]}, 2, "two"), "Second.\n\nCAMERA: Wide."); | |
| assert.equal(reviewPlanScenePrompt({shots: [ | |
| {id: "two", prompt: ["Moved second."]}, | |
| {id: "one", prompt: ["Moved first."]}, | |
| ]}, 2, "two"), "Moved second.", "scene id wins if the Plan was reordered"); | |
| assert.equal(reviewPlanScenePrompt({shots: []}, 1, "missing"), null); | |
| const plan = { | |
| prompt_prefix: ["Keep identity."], | |
| shots: [ | |
| {id: "one", prompt: ["Old one."], seed: "1"}, | |
| {id: "two", prompt: ["Old two."], seed: "2"}, | |
| ], | |
| }; | |
| applyReviewEdit(plan, 2, "New two.\n\nCAMERA: Close-up.", "9007199254740993", 56); | |
| assert.deepEqual(plan.shots[0].prompt, ["Old one."]); | |
| assert.deepEqual(plan.shots[1].prompt, ["New two.", "", "CAMERA: Close-up."]); | |
| assert.equal(plan.shots[1].seed, "9007199254740993"); | |
| assert.equal(plan.shots[1].length, 56); | |
| applyReviewEdit(plan, 1, "", "3"); | |
| assert.deepEqual(plan.shots[0].prompt, [""]); | |
| assert.equal(plan.shots[0].seed, "3"); | |
| assert.throws( | |
| () => applyReviewEdit({shots: [{prompt: [""]}]}, 1, "", "4"), | |
| /scene prompt or shared prompt/i, | |
| ); | |
| assert.deepEqual(reviewCountdown(130, 100_000), {seconds: 30, text: "0:30"}); | |
| assert.deepEqual(reviewCountdown(100, 100_001), {seconds: 0, text: "0:00"}); | |
| assert.equal(reviewCountdown(null, 0), null); | |
| assert.equal(reviewLocalDeadline(null, 100, 100_000), null); | |
| assert.equal(reviewLocalDeadline(undefined, 100, 100_000), null); | |
| assert.equal(reviewLocalDeadline("", 100, 100_000), null); | |
| assert.equal(reviewLocalDeadline(130, 100, 100_000), 130); | |
| assert.deepEqual(checkpointResumeOptions([ | |
| {scene: 2, resume_scene: 3, scene_id: "second", ready: true, | |
| video: {filename: "second.mp4"}}, | |
| {scene: 1, resume_scene: 2, scene_id: "first", ready: true, | |
| partial_video: {filename: "partial.mp4"}}, | |
| {scene: 3, resume_scene: 4, scene_id: "final", ready: true}, | |
| {scene: 1, resume_scene: 2, scene_id: "broken", ready: false}, | |
| ], 3), [ | |
| {savedScene: 1, resumeScene: 2, sceneId: "first", video: null, | |
| partialVideo: {filename: "partial.mp4"}}, | |
| {savedScene: 2, resumeScene: 3, sceneId: "second", | |
| video: {filename: "second.mp4"}, partialVideo: null}, | |
| ]); | |
| const revisionA = "a".repeat(32); | |
| const revisionB = "b".repeat(32); | |
| const revisionC = "c".repeat(32); | |
| assert.deepEqual(checkpointRevisionChain([ | |
| {scene: 1, revision: revisionA, active: false, ready: true, | |
| created_at: "2026-08-14T09:00:00", seed: "11", size_bytes: 1024}, | |
| {scene: 1, revision: revisionB, active: true, ready: true, | |
| created_at: "2026-08-14T10:00:00", seed: "12", size_bytes: 2048}, | |
| {scene: 2, revision: revisionC, active: true, ready: true, | |
| created_at: "2026-08-14T11:00:00", seed: "13", size_bytes: 4096}, | |
| {scene: 2, revision: "invalid", active: false, ready: true}, | |
| ], 3), [ | |
| {scene: 1, revisions: [ | |
| {scene: 1, sceneId: "clip_0001", revision: revisionB, active: true, | |
| createdAt: "2026-08-14T10:00:00", seed: "12", sizeBytes: 2048, | |
| promptPreview: "", video: null}, | |
| {scene: 1, sceneId: "clip_0001", revision: revisionA, active: false, | |
| createdAt: "2026-08-14T09:00:00", seed: "11", sizeBytes: 1024, | |
| promptPreview: "", video: null}, | |
| ]}, | |
| {scene: 2, revisions: [ | |
| {scene: 2, sceneId: "clip_0002", revision: revisionC, active: true, | |
| createdAt: "2026-08-14T11:00:00", seed: "13", sizeBytes: 4096, | |
| promptPreview: "", video: null}, | |
| ]}, | |
| ]); | |
| assert.deepEqual(checkpointRevisionChain([ | |
| {scene: 2, revision: revisionC, active: true, ready: true}, | |
| ], 3), [], "a recoverable chain must include every predecessor scene"); | |
| const recoveredPlan = applyCheckpointRevisionSet({ | |
| prompt_prefix: ["new prefix"], | |
| shots: [ | |
| {id: "one", prompt: ["new one"], length: 362, steps: 8, seed: "1", | |
| context_length: 39, audio_context_length: 44}, | |
| {id: "two", prompt: ["new two"], length: 362, steps: 8, seed: "2", | |
| context_length: 39, audio_context_length: 44}, | |
| ], | |
| }, [ | |
| {scene: 1, scene_id: "old_one", scene_prompt: "old one", seed: "101", | |
| raw_frames: 345, steps: 6, prompt_prefix: "old prefix", context_length: 0, | |
| audio_context_length: 33}, | |
| {scene: 2, scene_id: "old_two", scene_prompt: "old two", seed: "102", | |
| raw_frames: 328, steps: 7, prompt_prefix: "old prefix"}, | |
| ]); | |
| assert.deepEqual(recoveredPlan.prompt_prefix, ["old prefix"]); | |
| assert.deepEqual(recoveredPlan.shots, [ | |
| {id: "old_one", prompt: ["old one"], length: 345, steps: 6, seed: "101", | |
| context_length: 0, audio_context_length: 33}, | |
| {id: "old_two", prompt: ["old two"], length: 328, steps: 7, seed: "102"}, | |
| ]); | |
| const activatedAlternate = applyCheckpointRevisionSet({ | |
| prompt_prefix: ["current prefix"], | |
| shots: [ | |
| {id: "one", prompt: ["current one"], length: 362, steps: 8, | |
| seed: "1", lora_route: "d", prompt_seed_mode: "randomize"}, | |
| {id: "two", prompt: ["current two"], length: 362, steps: 8, | |
| seed: "2", context_spatial_proxy: "rgb_5_6"}, | |
| ], | |
| }, [ | |
| {scene: 1, scene_id: "old_one", scene_prompt: "{template|one}", | |
| effective_scene_prompt: "executed one", seed: "101", raw_frames: 345, | |
| steps: 6, prompt_prefix: "older prefix", context_length: 0, | |
| audio_context_length: 0, continuation_mode: "guide", | |
| video_blend_frames: 0, source_reference: "off", | |
| generated_continuity: "off", source_audio_target: "off", | |
| lora_route: "a", prompt_seed_mode: "fixed", prompt_seed: "9001"}, | |
| {scene: 2, scene_id: "old_two", scene_prompt: "{template|two}", | |
| effective_scene_prompt: "executed two", seed: "102", raw_frames: 328, | |
| steps: 7, prompt_prefix: "tip prefix", context_length: 39, | |
| audio_context_length: 39, visual_context_source: "old_one", | |
| continuation_mode: "masked_av", video_blend_frames: 2, | |
| context_spatial_proxy: "latent_5_6", source_reference: "on", | |
| generated_continuity: "on", source_audio_target: "locked", | |
| prompt_seed_mode: "randomize"}, | |
| ], {useEffectivePrompts: true, useTipSharedPrompt: true}); | |
| assert.deepEqual(activatedAlternate.prompt_prefix, ["tip prefix"]); | |
| assert.deepEqual(activatedAlternate.shots, [ | |
| {id: "old_one", prompt: ["executed one"], length: 345, steps: 6, | |
| seed: "101", context_length: 0, audio_context_length: 0, | |
| continuation_mode: "guide", video_blend_frames: 0, | |
| source_reference: "off", generated_continuity: "off", | |
| source_audio_target: "off", lora_route: "a", | |
| prompt_seed_mode: "fixed", prompt_seed: "9001"}, | |
| {id: "old_two", prompt: ["executed two"], length: 328, steps: 7, | |
| seed: "102", context_length: 39, audio_context_length: 39, | |
| visual_context_source: "old_one", continuation_mode: "masked_av", | |
| video_blend_frames: 2, context_spatial_proxy: "latent_5_6", | |
| source_reference: "on", generated_continuity: "on", | |
| source_audio_target: "locked", prompt_seed_mode: "randomize"}, | |
| ]); | |
| const restoredComposition = applyCheckpointRevisionSet({ | |
| prompt_prefix: ["keep"], | |
| shots: [ | |
| {id:"one", prompt:["one"], length:39, steps:8, seed:"1"}, | |
| {id:"two", prompt:["two"], length:39, steps:8, seed:"2"}, | |
| {id:"three", prompt:["three"], length:39, steps:8, seed:"3"}, | |
| ], | |
| }, [{ | |
| scene:3, scene_id:"three", scene_prompt:"three", seed:"303", | |
| raw_frames:39, steps:9, prompt_prefix:"keep", context_length:39, | |
| visual_context_source:"one", visual_context_lead_source:"two", | |
| visual_context_start_frame:2, visual_context_lead_frames:5, | |
| visual_context_lead_start_frame:3, video_blend_frames:0, | |
| }]); | |
| assert.equal(restoredComposition.shots[2].visual_context_source, "one"); | |
| assert.equal(restoredComposition.shots[2].visual_context_start_frame, 2); | |
| assert.equal(restoredComposition.shots[2].visual_context_lead_source, "two"); | |
| assert.equal(restoredComposition.shots[2].visual_context_lead_frames, 5); | |
| assert.equal(restoredComposition.shots[2].visual_context_lead_start_frame, 3); | |
| const restoredSameSource = applyCheckpointRevisionSet({ | |
| prompt_prefix: ["keep"], | |
| shots: [ | |
| {id:"one", prompt:["one"], length:39, steps:8, seed:"1"}, | |
| {id:"two", prompt:["two"], length:39, steps:8, seed:"2"}, | |
| {id:"three", prompt:["three"], length:39, steps:8, seed:"3"}, | |
| ], | |
| }, [{ | |
| scene:3, scene_id:"three", scene_prompt:"three", seed:"303", | |
| raw_frames:39, steps:9, prompt_prefix:"keep", context_length:39, | |
| visual_context_source:"one", visual_context_lead_source:"one", | |
| visual_context_lead_frames:5, video_blend_frames:0, | |
| }]); | |
| assert.equal(restoredSameSource.shots[2].visual_context_source, "one"); | |
| assert.equal(restoredSameSource.shots[2].visual_context_lead_source, "one"); | |
| const restoredBuilder = applyCheckpointRevisionSet({ | |
| prompt_prefix:["keep"], | |
| shots:[ | |
| {id:"one", prompt:["one"], length:90, steps:8, seed:"1"}, | |
| {id:"two", prompt:["two"], length:90, steps:8, seed:"2"}, | |
| {id:"three", prompt:["three"], length:90, steps:8, seed:"3", | |
| visual_context_source:"one"}, | |
| ], | |
| }, [{ | |
| scene:3, scene_id:"three", scene_prompt:"three", seed:"303", | |
| raw_frames:90, steps:9, prompt_prefix:"keep", context_length:39, | |
| visual_context_blocks:[ | |
| {source:"one", frames:5}, | |
| {source:"two", frames:12, start_frame:0}, | |
| {source:"one", frames:22}, | |
| ], video_blend_frames:0, | |
| }]); | |
| assert.deepEqual(restoredBuilder.shots[2].visual_context_blocks, [ | |
| {source:"one", frames:5}, | |
| {source:"two", frames:12, start_frame:0}, | |
| {source:"one", frames:22}, | |
| ]); | |
| assert.equal( | |
| Object.hasOwn(restoredBuilder.shots[2], "visual_context_source"), false, | |
| ); | |
| const seedOnlyPlan = applyCheckpointRevisionSeeds({ | |
| prompt_prefix: ["keep prefix"], | |
| shots: [ | |
| {id: "one", prompt: ["keep one"], length: 362, steps: 8, seed: "1"}, | |
| {id: "two", prompt: ["keep two"], length: 345, steps: 6, seed: "2"}, | |
| ], | |
| }, [ | |
| {scene: 1, seed: "101", scene_prompt: "ignored", raw_frames: 5, steps: 1}, | |
| {scene: 2, seed: "102", scene_prompt: "ignored", raw_frames: 5, steps: 1}, | |
| ]); | |
| assert.deepEqual(seedOnlyPlan, { | |
| prompt_prefix: ["keep prefix"], | |
| shots: [ | |
| {id: "one", prompt: ["keep one"], length: 362, steps: 8, seed: "101"}, | |
| {id: "two", prompt: ["keep two"], length: 345, steps: 6, seed: "102"}, | |
| ], | |
| }); | |
| const reviewSource = fs.readFileSync( | |
| new URL("../web/h3_chain_review_final.js", import.meta.url), | |
| "utf8", | |
| ); | |
| const backendSource = fs.readFileSync( | |
| new URL("../chain_nodes.py", import.meta.url), | |
| "utf8", | |
| ); | |
| assert.match(reviewSource, /minimax_h3_context_loop\/review/); | |
| assert.match(reviewSource, /minimax_h3_context_loop_review_resolved/); | |
| assert.match(reviewSource, /item\.name === "scene_range"/); | |
| assert.match(reviewSource, /rangeWidget\.value = range/); | |
| assert.match(reviewSource, /_h3QueuedReview/); | |
| assert.match(reviewSource, /setInterval[\s\S]*fetchPending/); | |
| assert.match(reviewSource, /addEventListener\("status", fetchPending\)/); | |
| assert.match(reviewSource, /async nodeCreated\(node\)/); | |
| assert.match(reviewSource, /gates\.length === 1/); | |
| assert.match(reviewSource, /data\?\.run_name/); | |
| assert.match(reviewSource, /mountedReviewNodes/); | |
| assert.match(reviewSource, /split\(\/\[\.:\]\//); | |
| assert.match(reviewSource, /No pending review is available for this project yet/); | |
| assert.match(reviewSource, /button\.disabled = false/); | |
| assert.doesNotMatch( | |
| reviewSource, | |
| /await fetchPending\(\);\s*return;/, | |
| "an action click must continue after recovering its pending token", | |
| ); | |
| assert.match(reviewSource, /"pointerdown", "pointerup", "mousedown", "mouseup", "click"/); | |
| assert.match(reviewSource, /preview_revision/); | |
| assert.match(reviewSource, /sameToken/); | |
| assert.match( | |
| reviewSource, | |
| /if \(!sameToken\)[\s\S]*setTimeout\(refreshResumeOptions, 0\)/, | |
| "a newly persisted review scene must refresh checkpoint history", | |
| ); | |
| assert.match( | |
| reviewSource, | |
| /data\.action === "approve" \|\| data\.action === "stop"[\s\S]*setTimeout\(refreshResumeOptions, 0\)/, | |
| "final approval must refresh checkpoint history", | |
| ); | |
| assert.match(reviewSource, /Checkpoint history/); | |
| assert.match(reviewSource, /const refreshToken = \+\+resumeRefreshToken/); | |
| assert.match(reviewSource, /if \(refreshToken !== resumeRefreshToken\) return/); | |
| assert.match(reviewSource, /candidate_revision/); | |
| assert.match(reviewSource, /Generate next candidate/); | |
| assert.match(reviewSource, /Accept now & continue/); | |
| assert.match(reviewSource, /review_each_candidate/); | |
| assert.match(reviewSource, /review-candidate-batch/); | |
| assert.match(reviewSource, /candidate_batch_active/); | |
| assert.match(reviewSource, /function planRunNameTrusted\(planNode\)/); | |
| assert.match(reviewSource, /item\.name === "project_assets"/); | |
| assert.match( | |
| reviewSource, | |
| /if \(planRunNameTrusted\(planNode\)\) \{[\s\S]*actualRun[\s\S]*actualRun !== expectedRun/, | |
| "an exact Review Gate must ignore the stale Plan run-name widget when Project Assets owns it", | |
| ); | |
| assert.match( | |
| reviewSource, | |
| /const matchingRun = gates\.filter\([\s\S]*if \(!planRunNameTrusted\(planNode\)\) return false/, | |
| "run-name fallback routing must not positively match a Project Assets-owned Plan", | |
| ); | |
| assert.match(reviewSource, /Pause candidate run/); | |
| assert.match(reviewSource, /\/api\/jobs\/\$\{encodeURIComponent\(execution\.promptId\)\}\/cancel/); | |
| assert.match(reviewSource, /activate_only: true/); | |
| assert.match(reviewSource, /action: "finalize"/); | |
| assert.match(reviewSource, /await app\.queuePrompt\(0, 1\)/); | |
| assert.doesNotMatch(reviewSource, /fetchApi\("\/interrupt"/); | |
| assert.match(reviewSource, /candidate_revisions/); | |
| assert.match(reviewSource, /keptCandidateRevisions/); | |
| assert.match(reviewSource, /h3r-candidate-dots/); | |
| assert.match(reviewSource, /moveCandidate/); | |
| assert.match(reviewSource, /exact video and audio continuation tensors/); | |
| assert.match(reviewSource, /function setReviewVideo/); | |
| assert.match(reviewSource, /video\.dataset\.source === source/); | |
| assert.match(reviewSource, /const carriedActiveCandidateRevision/); | |
| assert.match(reviewSource, /setReviewVideo\(candidate\.video, sameCandidate\)/); | |
| assert.match(reviewSource, /pinAcceptedPreview\(submittedReview, submittedCandidate\)/); | |
| assert.match(reviewSource, /acceptedDisposition === "ignore"/); | |
| assert.match(reviewSource, /if \(acceptedDisposition === "hold"\) showAcceptedPreview\(\)/); | |
| const showCandidateStart = reviewSource.indexOf("function showCandidate"); | |
| const showCandidateSource = reviewSource.slice( | |
| showCandidateStart, | |
| reviewSource.indexOf("function renderCandidateDots", showCandidateStart), | |
| ); | |
| assert.doesNotMatch( | |
| showCandidateSource, | |
| /video\.load\(\)/, | |
| "candidate progress refreshes must not reload the active preview", | |
| ); | |
| assert.match(reviewSource, /Candidate \$\{candidate\.number\}\/\$\{current\.candidate_count\}/); | |
| assert.match( | |
| reviewSource, | |
| /checkpointRevisionChain\(\s*checkpointRevisions, planClipCount \+ 1/, | |
| "checkpoint history must include the final scene, even though it cannot be a resume predecessor", | |
| ); | |
| assert.match(reviewSource, /revision\.scene < selectedResumeScene/); | |
| assert.match(reviewSource, /data\.final_video \?\? data\.partial_video/); | |
| assert.match(reviewSource, /final assembled video/); | |
| assert.match(reviewSource, /Duration \(s\)/); | |
| assert.match(reviewSource, /body\.length/); | |
| const submitStart = reviewSource.indexOf("async function submit"); | |
| const submitSource = reviewSource.slice( | |
| submitStart, | |
| reviewSource.indexOf("node._h3ReviewHandler", submitStart), | |
| ); | |
| assert.match(submitSource, /const submittedToken = submittedReview\.token/); | |
| assert.match(submitSource, /const submittedIndex = submittedReview\.clip_index/); | |
| assert.match(submitSource, /promptEditedInGate[\s\S]*planScenePrompt/); | |
| assert.match(submitSource, /reviewPromptEditorEnabled\(\)/); | |
| assert.match(submitSource, /planScenePrompt/); | |
| assert.match(submitSource, /token: submittedToken/); | |
| assert.match(submitSource, /scene_prompt: submittedPrompt/); | |
| assert.match( | |
| submitSource, | |
| /updatePlan\(\s*node, submittedIndex, acceptedPrompt, body\.seed, body\.length\)/, | |
| ); | |
| assert.match(reviewSource, /publishCompanionPrompt/); | |
| assert.match(reviewSource, /publishPlanCompanionScene/); | |
| assert.match(reviewSource, /_h3PromptCompanionSetScenePrompt/); | |
| assert.match(reviewSource, /reviewDurationText\(data\.raw_frames\)/); | |
| assert.match(reviewSource, /h3r-video-panel/); | |
| assert.match(reviewSource, /checkpoint-revisions\/restore/); | |
| assert.match(reviewSource, /checkpoint-revisions\/delete-preview/); | |
| assert.match(reviewSource, /checkpoint-revisions\/delete/); | |
| assert.match(reviewSource, /snapshot: preview\.snapshot/); | |
| const checkpointLoadStart = reviewSource.indexOf( | |
| 'loadResume.addEventListener("click"', | |
| ); | |
| const checkpointLoadSource = reviewSource.slice( | |
| checkpointLoadStart, | |
| reviewSource.indexOf("function stopCountdown", checkpointLoadStart), | |
| ); | |
| assert.match(checkpointLoadSource, /include_assets: "false"/); | |
| assert.match(checkpointLoadSource, /let restoredPolicyInputs = runBody\.policy_inputs/); | |
| assert.match(checkpointLoadSource, /restoredPolicyInputs = body\.policy_inputs/); | |
| assert.match( | |
| checkpointLoadSource, | |
| /restoreSavedPlanInputs\(\s*node, runBody\.plan_inputs, restoredPolicyInputs\)/, | |
| ); | |
| assert.match(reviewSource, /planNode, policyInputs, inputs/); | |
| assert.match(reviewSource, /refreshRestoredPlanEditors\(planNode\)/); | |
| assert.match( | |
| backendSource, | |
| /"policy_inputs": archive_policy_inputs\(\{\s*"compatibility": compatibility/, | |
| ); | |
| assert.match(checkpointLoadSource, /if \(selections\.length\)/); | |
| assert.ok( | |
| checkpointLoadSource.indexOf("restoreSavedPlanInputs") | |
| < checkpointLoadSource.indexOf("prepareResume"), | |
| "the complete saved Plan must be restored before Loop Start is armed", | |
| ); | |
| assert.match(reviewSource, /Permanently delete scene/); | |
| assert.match(reviewSource, /Restore & load/); | |
| assert.match(reviewSource, /h3r-video-grip/); | |
| assert.match(reviewSource, /h3_chain_review_video_height/); | |
| assert.match(reviewSource, /h3_chain_review_prompt_height/); | |
| assert.match(reviewSource, /promptResizeObserver = new ResizeObserver/); | |
| assert.match(reviewSource, /MiniMaxH3ContexLoop\.ReviewGate\.PromptEditor/); | |
| assert.match(reviewSource, /Enable prompt editing inside Review Gate/); | |
| assert.match(reviewSource, /defaultValue: false/); | |
| assert.match(reviewSource, /Prompt editing in Review Gate is disabled by default in 0\.5/); | |
| assert.match(reviewSource, /Scene Prompt Editor or Rich Scene Prompt Editor/); | |
| assert.match(reviewSource, /promptLabel\.hidden = !enabled/); | |
| assert.match(reviewSource, /promptNotice\.hidden = enabled/); | |
| assert.match(reviewSource, /_h3ReviewApplyLayout/); | |
| assert.match(reviewSource, /nodeType\.prototype\.onConfigure/); | |
| assert.match(reviewSource, /setPointerCapture/); | |
| assert.match(reviewSource, /visualHeight \/ layoutHeight/); | |
| assert.match(reviewSource, /videoPanel\.offsetHeight, true/); | |
| assert.doesNotMatch(reviewSource, /\/h3_motion_context\/review/); | |
| console.log("H3 Chain Review editor helpers: ok"); | |