test(browser): avoid selector scripts in e2e

Pass WebDriver-found elements into browser E2E helper scripts and build the probe island with DOM APIs, keeping test-only JavaScript from reintroducing querySelector or unchecked HTML insertion.

req: runtime/001

req: examples/005
This commit is contained in:
slhx agent
2026-06-02 00:11:55 +02:00
parent 9dd32c3165
commit 7b7cb7da15
+32 -22
View File
@@ -138,43 +138,53 @@ fn card_button_selector(handle_id: impl std::fmt::Display, work_id: u64) -> Stri
}
async fn insert_probe_island(driver: &WebDriver) -> WebDriverResult<()> {
let root = driver.find(By::Css("[data-slhx-root]")).await?;
driver
.execute(
r#"
document.querySelector('[data-slhx-root]').insertAdjacentHTML('beforeend', `
<article id="probe-island" data-slhx-island="orbit" data-island-snapshot="1|1|1|probe waiting">
<canvas width="32" height="16"></canvas>
<p data-island-readout="">waiting</p>
</article>
`);
const root = arguments[0];
const island = document.createElement('article');
island.id = 'probe-island';
island.setAttribute('data-slhx-island', 'orbit');
island.setAttribute('data-island-snapshot', '1|1|1|probe waiting');
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 16;
island.appendChild(canvas);
const readout = document.createElement('p');
readout.setAttribute('data-island-readout', '');
readout.textContent = 'waiting';
island.appendChild(readout);
root.appendChild(island);
setTimeout(() => {
document.querySelector('[data-slhx-root]').dispatchEvent(new CustomEvent('slhx:island-orbit', { bubbles: true, detail: '7|2|8|probe live' }));
root.dispatchEvent(new CustomEvent('slhx:island-orbit', { bubbles: true, detail: '7|2|8|probe live' }));
}, 25);
return true;
"#,
Vec::new(),
vec![root.to_json()?],
)
.await?;
Ok(())
}
async fn drag_card_to_lane(driver: &WebDriver, work_id: u64, lane: &str) -> WebDriverResult<()> {
let card = driver.find(By::Css(format!(".work-card[data-key='{work_id}']"))).await?;
let lane = driver.find(By::Css(format!(".lane[data-lane='{lane}']"))).await?;
driver
.execute(
&format!(
r#"
const card = document.querySelector({:?});
const lane = document.querySelector({:?});
const data = new DataTransfer();
card.dispatchEvent(new DragEvent('dragstart', {{ bubbles: true, dataTransfer: data }}));
lane.dispatchEvent(new DragEvent('dragover', {{ bubbles: true, cancelable: true, dataTransfer: data }}));
lane.dispatchEvent(new DragEvent('drop', {{ bubbles: true, cancelable: true, dataTransfer: data }}));
return true;
"#,
format!(".work-card[data-key='{work_id}']"),
format!(".lane[data-lane='{lane}']"),
),
Vec::new(),
r#"
const card = arguments[0];
const lane = arguments[1];
const data = new DataTransfer();
card.dispatchEvent(new DragEvent('dragstart', { bubbles: true, dataTransfer: data }));
lane.dispatchEvent(new DragEvent('dragover', { bubbles: true, cancelable: true, dataTransfer: data }));
lane.dispatchEvent(new DragEvent('drop', { bubbles: true, cancelable: true, dataTransfer: data }));
return true;
"#,
vec![card.to_json()?, lane.to_json()?],
)
.await?;
Ok(())