refactor!: rename slhx to hemx
Rename the tracked product identity, crate/package names, Rust paths/macros, generated artifacts, runtime files, public attributes, examples, docs, requirements, and tests from slhx to hemx without compatibility shims. Verified with cargo run -p hemx-xtask -- test, cargo test -p hemx-derive --test compile_fail, cargo test -p hemx-js, cargo test -p hemx-axum, cargo test -p hemx-v0-examples, cargo check --workspace, redgate list, redgate refs, redgate health --strict, git diff --check, and git grep/ls-files legacy-name audits. req: misc/001 req: codegen/001 req: component/004 req: runtime/001
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "slhx-techdemo"
|
||||
name = "hemx-techdemo"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
publish = false
|
||||
@@ -11,14 +11,14 @@ path = "src/lib.rs"
|
||||
axum = "0.7"
|
||||
futures-util = "0.3"
|
||||
hemplate = { path = "../../../hemplate/hemplate" }
|
||||
slhx = { path = "../../slhx" }
|
||||
slhx-axum = { path = "../../slhx-axum" }
|
||||
hemx = { path = "../../hemx" }
|
||||
hemx-axum = { path = "../../hemx-axum" }
|
||||
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "time"] }
|
||||
|
||||
[dev-dependencies]
|
||||
scraper = "0.23"
|
||||
slhx-test = { path = "../../slhx-test" }
|
||||
hemx-test = { path = "../../hemx-test" }
|
||||
thirtyfour = "0.35"
|
||||
|
||||
[build-dependencies]
|
||||
slhx-build = { path = "../../slhx-build" }
|
||||
hemx-build = { path = "../../hemx-build" }
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# slhx full techdemo
|
||||
# hemx full techdemo
|
||||
|
||||
Run:
|
||||
|
||||
cargo run -p slhx-techdemo
|
||||
cargo run -p hemx-techdemo
|
||||
|
||||
Open <http://127.0.0.1:3002>.
|
||||
|
||||
This is a polished Linear-style product demo for planning typed work across lanes. It is tailored to showcase slhx strengths:
|
||||
This is a polished Linear-style product demo for planning typed work across lanes. It is tailored to showcase hemx strengths:
|
||||
|
||||
- modern SSR-first UI
|
||||
- generated target objects from `.heml`
|
||||
@@ -17,12 +17,12 @@ This is a polished Linear-style product demo for planning typed work across lane
|
||||
- root-scoped runtime application without selector lookups
|
||||
- page-enhancer navigation with native link fallback
|
||||
- SSE server push into a generated slot
|
||||
- drag-and-drop lane moves persisted by typed server handlers through the slhx runtime
|
||||
- an explicit advanced opaque canvas island fed by a generated event helper, without teaching slhx core about the widget
|
||||
- no user-authored browser JavaScript in slhx-managed UI; the island JavaScript is a leaf-widget escape hatch
|
||||
- drag-and-drop lane moves persisted by typed server handlers through the hemx runtime
|
||||
- an explicit advanced opaque canvas island fed by a generated event helper, without teaching hemx core about the widget
|
||||
- no user-authored browser JavaScript in hemx-managed UI; the island JavaScript is a leaf-widget escape hatch
|
||||
|
||||
Verification:
|
||||
|
||||
cargo test -p slhx-techdemo --test e2e
|
||||
cargo test -p slhx-techdemo --test browser_e2e
|
||||
mutest -p slhx-techdemo -f examples/techdemo/src/main.rs -F 'registry' -j 2 --timeout 90 -- --test e2e
|
||||
cargo test -p hemx-techdemo --test e2e
|
||||
cargo test -p hemx-techdemo --test browser_e2e
|
||||
mutest -p hemx-techdemo -f examples/techdemo/src/main.rs -F 'registry' -j 2 --timeout 90 -- --test e2e
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
fn main() {
|
||||
slhx_build::app().run().unwrap();
|
||||
hemx_build::app().run().unwrap();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#[slhx::surface]
|
||||
#[hemx::surface]
|
||||
pub mod ui {}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -7,8 +7,8 @@ mod tests {
|
||||
use super::ui::issue_card::advance_work;
|
||||
use super::ui::issue_lane::events as lane_events;
|
||||
use hemplate::Hemplate;
|
||||
use slhx::IntoEffect;
|
||||
use slhx_test::inspect;
|
||||
use hemx::IntoEffect;
|
||||
use hemx_test::inspect;
|
||||
|
||||
#[derive(Hemplate)]
|
||||
#[hemplate = "partials"]
|
||||
@@ -18,7 +18,7 @@ mod tests {
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Debug)]
|
||||
#[slhx::form("launch_work")]
|
||||
#[hemx::form("launch_work")]
|
||||
struct LaunchWork {
|
||||
title: String,
|
||||
lane: String,
|
||||
@@ -43,8 +43,8 @@ mod tests {
|
||||
// req: examples/001 req: form/001 req: form/004 req: form/006 req: derive_handler/003
|
||||
#[test]
|
||||
fn techdemo_form_handler_is_checked_against_hemplate_form() {
|
||||
#[slhx::handler]
|
||||
fn launch_work(_form: slhx::Form<LaunchWork>) -> impl IntoEffect {
|
||||
#[hemx::handler]
|
||||
fn launch_work(_form: hemx::Form<LaunchWork>) -> impl IntoEffect {
|
||||
notice.text("queued")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,14 @@ use axum::routing::get;
|
||||
use axum::Router;
|
||||
use futures_util::{stream, StreamExt};
|
||||
use hemplate::Hemplate;
|
||||
use slhx::{CssClass, CssClasses, EventName, Html, IntoEffect};
|
||||
use slhx_axum::{
|
||||
use hemx::{CssClass, CssClasses, EventName, Html, IntoEffect};
|
||||
use hemx_axum::{
|
||||
interactions, runtime_js, sse, DispatchRegistry, DispatchRejection, EffectResponse,
|
||||
InteractionRequest, PageRequest,
|
||||
};
|
||||
use slhx_techdemo::ui;
|
||||
use slhx_techdemo::ui::control_center::{self as control, classes};
|
||||
use slhx_techdemo::ui::{issue_card as card_control, issue_lane as lane_control};
|
||||
use hemx_techdemo::ui;
|
||||
use hemx_techdemo::ui::control_center::{self as control, classes};
|
||||
use hemx_techdemo::ui::{issue_card as card_control, issue_lane as lane_control};
|
||||
use std::collections::{BTreeMap, VecDeque};
|
||||
use std::convert::Infallible;
|
||||
use std::net::SocketAddr;
|
||||
@@ -24,7 +24,7 @@ const LANES: [(&str, &str, &str); 3] = [
|
||||
("runtime", "Runtime", "typed updates → DOM"),
|
||||
("product", "Product", "Native UX, zero app JS"),
|
||||
];
|
||||
const ISLAND_ORBIT: EventName = EventName::new("slhx:island-orbit");
|
||||
const ISLAND_ORBIT: EventName = EventName::new("hemx:island-orbit");
|
||||
|
||||
#[derive(Clone)]
|
||||
struct WorkItem {
|
||||
@@ -226,18 +226,18 @@ async fn main() {
|
||||
.route("/architecture", get(architecture))
|
||||
.route("/events", get(events))
|
||||
.route("/favicon.ico", get(favicon))
|
||||
.route("/slhx.js", get(runtime))
|
||||
.route("/hemx.js", get(runtime))
|
||||
.route("/app.css", get(app_css))
|
||||
.route("/control_center.css", get(control_center_css))
|
||||
.route("/island.js", get(island_js))
|
||||
.with_state(state);
|
||||
|
||||
let addr = std::env::var("SLHX_TECHDEMO_ADDR")
|
||||
let addr = std::env::var("HEMX_TECHDEMO_ADDR")
|
||||
.ok()
|
||||
.and_then(|addr| addr.parse().ok())
|
||||
.unwrap_or_else(|| SocketAddr::from(([127, 0, 0, 1], 3002)));
|
||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||
println!("slhx techdemo: http://{addr}");
|
||||
println!("hemx techdemo: http://{addr}");
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ async fn home(State(state): State<Arc<Shared>>, request: PageRequest) -> impl In
|
||||
let demo = state.demo.lock().unwrap().clone();
|
||||
request
|
||||
.page_html(page_html(&demo), shell)
|
||||
.title("slhx Techdemo")
|
||||
.title("hemx Techdemo")
|
||||
.fingerprint(ui::BUILD_FINGERPRINT)
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ async fn architecture(request: PageRequest) -> impl IntoResponse {
|
||||
});
|
||||
request
|
||||
.page_html(body, shell)
|
||||
.title("slhx Architecture")
|
||||
.title("hemx Architecture")
|
||||
.fingerprint(ui::BUILD_FINGERPRINT)
|
||||
}
|
||||
|
||||
@@ -659,11 +659,11 @@ mod tests {
|
||||
.select(&selector("title"))
|
||||
.next()
|
||||
.map(|title| title.text().collect::<String>()),
|
||||
Some("slhx Techdemo".to_owned())
|
||||
Some("hemx Techdemo".to_owned())
|
||||
);
|
||||
assert_eq!(
|
||||
document
|
||||
.select(&selector("script[src=\"/slhx.js\"]"))
|
||||
.select(&selector("script[src=\"/hemx.js\"]"))
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
@@ -687,7 +687,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
document
|
||||
.select(&selector("main[data-slhx-root=\"techdemo\"]"))
|
||||
.select(&selector("main[data-hemx-root=\"techdemo\"]"))
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
@@ -706,7 +706,7 @@ mod tests {
|
||||
let document = Html::parse_fragment(html.as_str());
|
||||
assert_eq!(
|
||||
document
|
||||
.select(&selector("[data-slhx-root=\"techdemo\"]"))
|
||||
.select(&selector("[data-hemx-root=\"techdemo\"]"))
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
@@ -853,7 +853,7 @@ mod tests {
|
||||
assert_eq!(items.len(), 3);
|
||||
assert_eq!(
|
||||
items[1].text().collect::<String>(),
|
||||
"Fetched HTML with X-SLHX-Partial"
|
||||
"Fetched HTML with X-HEMX-Partial"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ main { width:min(1180px, calc(100vw - 32px)); margin:0 auto; padding:38px 0 56px
|
||||
.hero-shell { display:grid; grid-template-columns:1.35fr .85fr; gap:22px; align-items:stretch; }
|
||||
.hero-copy, .hero-panel, .command-card, .board-card, .glass-card, .topology { border:1px solid var(--line); background:linear-gradient(145deg, rgba(255,255,255,.14), rgba(255,255,255,.055)); box-shadow:0 24px 90px rgba(0,0,0,.36), inset 0 1px 0 rgba(255,255,255,.12); backdrop-filter: blur(22px) saturate(145%); border-radius:28px; }
|
||||
.hero-copy { padding:34px; overflow:hidden; position:relative; }
|
||||
.hero-copy::after { content:"slhx"; position:absolute; right:-18px; bottom:8px; font-size:86px; font-weight:900; color:rgba(255,255,255,.045); }
|
||||
.hero-copy::after { content:"hemx"; position:absolute; right:-18px; bottom:8px; font-size:86px; font-weight:900; color:rgba(255,255,255,.045); }
|
||||
.eyebrow { color:var(--cyan); text-transform:uppercase; letter-spacing:.2em; font-weight:800; font-size:12px; }
|
||||
h1 { font-size:clamp(42px, 7vw, 84px); line-height:.88; letter-spacing:-.075em; margin:12px 0 18px; max-width:900px; text-wrap:balance; overflow-wrap:anywhere; }
|
||||
h2 { margin:0 0 16px; letter-spacing:-.035em; }
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>slhx Techdemo</title>
|
||||
<script src="/slhx.js" defer></script>
|
||||
<title>hemx Techdemo</title>
|
||||
<script src="/hemx.js" defer></script>
|
||||
<script src="/island.js" defer></script>
|
||||
<link rel="stylesheet" href="/app.css">
|
||||
<link rel="stylesheet" href="/control_center.css">
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<main data-slhx-root="techdemo" data-slhx-sse="/events">
|
||||
<main data-hemx-root="techdemo" data-hemx-sse="/events">
|
||||
<section class="hero-shell">
|
||||
<div class="hero-copy">
|
||||
<p class="eyebrow">slhx Control Plane</p>
|
||||
<p class="eyebrow">hemx Control Plane</p>
|
||||
<h1>A Linear-class work system without a frontend framework.</h1>
|
||||
<p class="lede">Create, inspect, advance, and stream work through native HTML, generated typed resources, and compact update batches. The UI feels app-grade; the model stays server-owned and boring.</p>
|
||||
</div>
|
||||
<div class="hero-panel" data-slhx-slot="hero_metrics">{+= self.hero =+}</div>
|
||||
<div class="hero-panel" data-hemx-slot="hero_metrics">{+= self.hero =+}</div>
|
||||
</section>
|
||||
|
||||
<nav class="topology" data-slhx-slot="nav">
|
||||
<a href="/" data-slhx-nav="">Live system</a>
|
||||
<a href="/architecture" data-slhx-nav="">Architecture</a>
|
||||
<nav class="topology" data-hemx-slot="nav">
|
||||
<a href="/" data-hemx-nav="">Live system</a>
|
||||
<a href="/architecture" data-hemx-nav="">Architecture</a>
|
||||
</nav>
|
||||
|
||||
<section class="workspace">
|
||||
<aside class="command-card">
|
||||
<h2>Create an issue</h2>
|
||||
<form id="launch-work" method="post" data-slhx-handle="launch_work" data-slhx-form="launch_work" data-slhx-disable-while-pending>
|
||||
<form id="launch-work" method="post" data-hemx-handle="launch_work" data-hemx-form="launch_work" data-hemx-disable-while-pending>
|
||||
<label>Title <input name="title" required="required" value="Ship typed updates"></label>
|
||||
<label>Lane
|
||||
<select name="lane" required="required">
|
||||
@@ -26,13 +26,13 @@
|
||||
</select>
|
||||
</label>
|
||||
<label>Impact <input name="impact" type="number" min="1" max="9" value="7"></label>
|
||||
<button class="primary-action" type="button" form="launch-work" data-slhx-handle="launch_work">Create issue</button>
|
||||
<button class="primary-action" type="button" form="launch-work" data-hemx-handle="launch_work">Create issue</button>
|
||||
</form>
|
||||
<div class="quick-actions">
|
||||
<button type="button" data-slhx-handle="simulate_push">Simulate server push</button>
|
||||
<button type="button" data-slhx-handle="reset_demo">Reset demo</button>
|
||||
<button type="button" data-hemx-handle="simulate_push">Simulate server push</button>
|
||||
<button type="button" data-hemx-handle="reset_demo">Reset demo</button>
|
||||
</div>
|
||||
<p data-slhx-slot="notice" class="notice">Every control posts through a generated handle and receives typed updates.</p>
|
||||
<p data-hemx-slot="notice" class="notice">Every control posts through a generated handle and receives typed updates.</p>
|
||||
</aside>
|
||||
|
||||
<section class="board-card">
|
||||
@@ -40,27 +40,27 @@
|
||||
<span>Generated slots + keyed cards</span>
|
||||
<strong>generated resources, no selectors</strong>
|
||||
</div>
|
||||
<div data-slhx-slot="board">{+= self.board =+}</div>
|
||||
<div data-hemx-slot="board">{+= self.board =+}</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="insight-grid">
|
||||
<article class="glass-card">
|
||||
<h2>Update inspector</h2>
|
||||
<div data-slhx-slot="inspector" class="inspector-slot">{+= self.inspector =+}</div>
|
||||
<div data-hemx-slot="inspector" class="inspector-slot">{+= self.inspector =+}</div>
|
||||
</article>
|
||||
<article class="glass-card island-card" data-slhx-island="orbit" +data-island-snapshot="self.island_snapshot">
|
||||
<article class="glass-card island-card" data-hemx-island="orbit" +data-island-snapshot="self.island_snapshot">
|
||||
<h2>Opaque island bridge</h2>
|
||||
<canvas width="360" height="180" aria-label="Animated island orbit"></canvas>
|
||||
<p data-island-readout="">Waiting for Rust snapshot…</p>
|
||||
</article>
|
||||
<article class="glass-card">
|
||||
<h2>Activity stream</h2>
|
||||
<div data-slhx-slot="activity">{+= self.activity =+}</div>
|
||||
<div data-hemx-slot="activity">{+= self.activity =+}</div>
|
||||
</article>
|
||||
<article class="glass-card glow">
|
||||
<h2>Server push</h2>
|
||||
<div data-slhx-slot="live_feed" class="live-feed">Waiting for SSE heartbeat…</div>
|
||||
<div data-hemx-slot="live_feed" class="live-feed">Waiting for SSE heartbeat…</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Opaque leaf-widget island. slhx talks to it only with native CustomEvent payloads.
|
||||
// Opaque leaf-widget island. hemx talks to it only with native CustomEvent payloads.
|
||||
// req: interop/001 req: examples/001
|
||||
(() => {
|
||||
const roots = new WeakMap();
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
function rootOf(node) {
|
||||
for (let el = node; el; el = el.parentElement) {
|
||||
if (el.hasAttribute && el.hasAttribute("data-slhx-root")) return el;
|
||||
if (el.hasAttribute && el.hasAttribute("data-hemx-root")) return el;
|
||||
}
|
||||
return document.documentElement;
|
||||
}
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
ctx.fillStyle = "#fff";
|
||||
ctx.font = "700 16px system-ui, sans-serif";
|
||||
ctx.fillText("slhx island", 18, 30);
|
||||
ctx.fillText("hemx island", 18, 30);
|
||||
ctx.font = "12px system-ui, sans-serif";
|
||||
ctx.fillStyle = "rgba(255,255,255,.74)";
|
||||
ctx.fillText(`cards ${state.snapshot.cards} · impact ${state.snapshot.impact} · boost ${state.snapshot.power}`, 18, 50);
|
||||
@@ -85,11 +85,11 @@
|
||||
state.snapshot = parseSnapshot(event.detail);
|
||||
island.setAttribute("data-island-snapshot", event.detail);
|
||||
};
|
||||
root.addEventListener("slhx:island-orbit", update);
|
||||
root.addEventListener("hemx:island-orbit", update);
|
||||
|
||||
function tick() {
|
||||
if (!document.contains(island)) {
|
||||
root.removeEventListener("slhx:island-orbit", update);
|
||||
root.removeEventListener("hemx:island-orbit", update);
|
||||
return;
|
||||
}
|
||||
state.frame += 1;
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
function scan() {
|
||||
forEachElement(document, (el) => {
|
||||
if (el.hasAttribute("data-slhx-island")) boot(el);
|
||||
if (el.hasAttribute("data-hemx-island")) boot(el);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<ol class="activity">
|
||||
<li>Clicked a real anchor</li>
|
||||
<li>Fetched HTML with X-SLHX-Partial</li>
|
||||
<li>Fetched HTML with X-HEMX-Partial</li>
|
||||
<li>Preserved native fallback semantics</li>
|
||||
</ol>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="lanes">
|
||||
<section class="lane"><h3>hemplate</h3><p>Owns syntax and Surface facts.</p></section>
|
||||
<section class="lane"><h3>slhx-build</h3><p>Generates resources and lowering tables.</p></section>
|
||||
<section class="lane"><h3>hemx-build</h3><p>Generates resources and lowering tables.</p></section>
|
||||
<section class="lane"><h3>runtime</h3><p>Executes compact typed DOM ops.</p></section>
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<header><strong>{+ self.title +}</strong><span class="pill">{+ self.stage +}</span></header>
|
||||
<div class="impact"><i +style="self.impact_style"></i></div>
|
||||
<div class="card-actions">
|
||||
<button type="button" data-slhx-handle="spotlight_work" +data-work-id="self.id" name="work_id" +value="self.id">Inspect</button>
|
||||
<button type="button" data-slhx-handle="advance_work" +data-work-id="self.id" name="work_id" +value="self.id">Advance</button>
|
||||
<button type="button" data-slhx-handle="delete_work" +data-work-id="self.id" name="work_id" +value="self.id">Delete</button>
|
||||
<button type="button" data-hemx-handle="spotlight_work" +data-work-id="self.id" name="work_id" +value="self.id">Inspect</button>
|
||||
<button type="button" data-hemx-handle="advance_work" +data-work-id="self.id" name="work_id" +value="self.id">Advance</button>
|
||||
<button type="button" data-hemx-handle="delete_work" +data-work-id="self.id" name="work_id" +value="self.id">Delete</button>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<section +class="self.class" +data-lane="self.lane_id" data-slhx-handle="move_to_lane" data-slhx-on="drop">
|
||||
<section +class="self.class" +data-lane="self.lane_id" data-hemx-handle="move_to_lane" data-hemx-on="drop">
|
||||
<h3>{+ self.title +}</h3>
|
||||
<p>{+ self.description +}</p>
|
||||
<template h-for="card in &self.cards">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use slhx_techdemo::ui::control_center::{self as control, launch_work, simulate_push};
|
||||
use slhx_test::{
|
||||
use hemx_techdemo::ui::control_center::{self as control, launch_work, simulate_push};
|
||||
use hemx_test::{
|
||||
any_root_selector, document_body_selector, handle_button_selector, handle_selector,
|
||||
island_probe_script, island_readout_selector, keyed_selector, nav_link_selector,
|
||||
scoped_island_readout_selector, target_selector,
|
||||
@@ -36,8 +36,8 @@ impl Drop for ChildProcess {
|
||||
#[tokio::test]
|
||||
async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> {
|
||||
// req: examples/001 req: dx/008 req: form/002 req: page_swap/002 req: push/003
|
||||
let mut app = Command::new(env!("CARGO_BIN_EXE_slhx-techdemo"));
|
||||
app.env("SLHX_TECHDEMO_ADDR", APP_ADDR);
|
||||
let mut app = Command::new(env!("CARGO_BIN_EXE_hemx-techdemo"));
|
||||
app.env("HEMX_TECHDEMO_ADDR", APP_ADDR);
|
||||
let _app = ChildProcess::spawn(app);
|
||||
wait_for_tcp(APP_ADDR);
|
||||
|
||||
@@ -153,7 +153,7 @@ async fn wait_for_runtime(driver: &WebDriver) -> WebDriverResult<()> {
|
||||
loop {
|
||||
let loaded = driver
|
||||
.execute(
|
||||
"return !!window.slhx && window.slhx.roots().length > 0",
|
||||
"return !!window.hemx && window.hemx.roots().length > 0",
|
||||
Vec::new(),
|
||||
)
|
||||
.await?
|
||||
@@ -164,7 +164,7 @@ async fn wait_for_runtime(driver: &WebDriver) -> WebDriverResult<()> {
|
||||
return Ok(());
|
||||
}
|
||||
if Instant::now() >= deadline {
|
||||
panic!("timed out waiting for slhx runtime");
|
||||
panic!("timed out waiting for hemx runtime");
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use scraper::{Html, Selector};
|
||||
use slhx_techdemo::ui::control_center::{self as control, launch_work, reset_demo, simulate_push};
|
||||
use slhx_techdemo::ui::issue_card::{advance_work, delete_work, spotlight_work};
|
||||
use slhx_techdemo::ui::issue_lane::move_to_lane as move_to_lane_handle;
|
||||
use slhx_techdemo::ui::BUILD_FINGERPRINT;
|
||||
use slhx_test::{
|
||||
use hemx_techdemo::ui::control_center::{self as control, launch_work, reset_demo, simulate_push};
|
||||
use hemx_techdemo::ui::issue_card::{advance_work, delete_work, spotlight_work};
|
||||
use hemx_techdemo::ui::issue_lane::move_to_lane as move_to_lane_handle;
|
||||
use hemx_techdemo::ui::BUILD_FINGERPRINT;
|
||||
use hemx_test::{
|
||||
class_descendant_selector, class_selector, handle_form_body, inspect_wire,
|
||||
island_attribute_name, island_event_name, island_selector, island_snapshot_marker,
|
||||
root_selector, sse_endpoint_marker, strong_text_selector, unknown_handle_form_body,
|
||||
@@ -22,12 +22,12 @@ struct Server {
|
||||
|
||||
impl Server {
|
||||
fn start() -> Self {
|
||||
let bin = env!("CARGO_BIN_EXE_slhx-techdemo");
|
||||
let bin = env!("CARGO_BIN_EXE_hemx-techdemo");
|
||||
let child = Command::new(bin)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.spawn()
|
||||
.expect("start slhx-techdemo");
|
||||
.expect("start hemx-techdemo");
|
||||
|
||||
let deadline = Instant::now() + Duration::from_secs(5);
|
||||
while Instant::now() < deadline {
|
||||
@@ -36,7 +36,7 @@ impl Server {
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(25));
|
||||
}
|
||||
panic!("slhx-techdemo did not listen on {ADDR}");
|
||||
panic!("hemx-techdemo did not listen on {ADDR}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ fn product_is_e2e_working_over_http() {
|
||||
let favicon = get("/favicon.ico");
|
||||
assert_eq!(favicon.status, 204);
|
||||
|
||||
let runtime = get("/slhx.js");
|
||||
let runtime = get("/hemx.js");
|
||||
assert_eq!(runtime.status, 200);
|
||||
assert!(runtime.header("content-type").contains("javascript"));
|
||||
|
||||
@@ -85,12 +85,12 @@ fn product_is_e2e_working_over_http() {
|
||||
assert!(island.text().contains("MutationObserver"));
|
||||
assert!(island.text().contains("removeEventListener"));
|
||||
|
||||
let architecture = request("GET", "/architecture", &[("X-SLHX-Partial", "1")], "");
|
||||
let architecture = request("GET", "/architecture", &[("X-HEMX-Partial", "1")], "");
|
||||
assert_eq!(architecture.status, 200);
|
||||
assert!(architecture.header("x-slhx-partial").contains("true"));
|
||||
assert!(architecture.header("x-hemx-partial").contains("true"));
|
||||
let architecture_doc = Html::parse_document(architecture.text());
|
||||
assert_text(&architecture_doc, "Page swap");
|
||||
assert_text(&architecture_doc, "slhx-build");
|
||||
assert_text(&architecture_doc, "hemx-build");
|
||||
|
||||
let launch = post(
|
||||
"/",
|
||||
@@ -277,19 +277,19 @@ fn product_is_e2e_working_over_http() {
|
||||
let sse = get("/events?once=1");
|
||||
assert_eq!(sse.status, 200);
|
||||
assert!(sse.header("content-type").contains("text/event-stream"));
|
||||
assert!(sse.text().contains("event: slhx"));
|
||||
assert!(sse.text().contains("event: hemx"));
|
||||
assert!(sse.text().contains("data: "));
|
||||
|
||||
let unknown = post("/", &unknown_handle_form_body(999999));
|
||||
assert_eq!(unknown.status, 404);
|
||||
assert!(unknown.text().contains("unknown slhx handle id 999999"));
|
||||
assert!(unknown.text().contains("unknown hemx handle id 999999"));
|
||||
}
|
||||
|
||||
fn assert_effect_response(response: &Response) {
|
||||
assert_eq!(response.status, 200);
|
||||
assert!(response.header("content-type").contains("application/slhx"));
|
||||
assert!(response.header("content-type").contains("application/hemx"));
|
||||
assert_eq!(
|
||||
response.header("x-slhx-fingerprint"),
|
||||
response.header("x-hemx-fingerprint"),
|
||||
BUILD_FINGERPRINT.0.to_string()
|
||||
);
|
||||
assert!(!response.effects().is_empty());
|
||||
|
||||
Reference in New Issue
Block a user