seat tray: tray.js, SCSS, FTs, Jasmine specs

- new apps.epic.static tray.js: IIFE with drag-open/click-close/wobble
  behaviour; document-level pointermove+mouseup listeners; reset() for
  Jasmine afterEach; try/catch around setPointerCapture for synthetic events
- _room.scss: #id_tray_wrap fixed-right flex container; #id_tray_handle +
  #id_tray_grip (box-shadow frame, transparent inner window, border-radius
  clip); #id_tray_btn grab cursor; #id_tray bevel box-shadows, margin-left
  gap, height removed (align-items:stretch handles it); tray-wobble keyframes
- _applets.scss + _game-kit.scss: z-index raised (312-318) for primacy over
  tray (310)
- room.html: #id_tray_wrap + children markup; tray.js script tag
- FTs test_room_tray: 5 tests (T1-T5); _simulate_drag via execute_script
  pointer events (replaces unreliable ActionChains drag); wobble asserts on
  #id_tray_wrap not btn
- static_src/tests/TraySpec.js + SpecRunner.html: Jasmine unit tests for
  all tray.js branches

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-03-28 18:52:46 -04:00
parent 30ea0fad9d
commit b35c9b483e
22 changed files with 16193 additions and 18 deletions

57
src/static/tests/Spec.js Normal file
View File

@@ -0,0 +1,57 @@
console.log("Spec.js is loading");
describe("GameArray JavaScript", () => {
const inputId= "id_text";
const errorClass = "invalid-feedback";
const inputSelector = `#${inputId}`;
const errorSelector = `.${errorClass}`;
let testDiv;
let textInput;
let errorMsg;
beforeEach(() => {
console.log("beforeEach");
testDiv = document.createElement("div");
testDiv.innerHTML = `
<form>
<input
id="${inputId}"
name="text"
class="form-control form-control-lg is-invalid"
placeholder="Enter a to-do item"
value="Value as submitted"
aria-describedby="id_text_feedback"
required
/>
<div id="id_text_feedback" class="${errorClass}">An error message</div>
</form>
`;
document.body.appendChild(testDiv);
textInput = document.querySelector(inputSelector);
errorMsg = document.querySelector(errorSelector);
});
afterEach(() => {
testDiv.remove();
});
it("should have a useful html fixture", () => {
console.log("in test 1");
expect(errorMsg.checkVisibility()).toBe(true);
});
it("should hide error message on input", () => {
console.log("in test 2");
initialize(inputSelector);
textInput.dispatchEvent(new InputEvent("input"));
expect(errorMsg.checkVisibility()).toBe(false);
});
it("should not hide error message before event is fired", () => {
console.log("in test 3");
initialize(inputSelector);
expect(errorMsg.checkVisibility()).toBe(true);
});
});