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:
@@ -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<()> {
|
async fn insert_probe_island(driver: &WebDriver) -> WebDriverResult<()> {
|
||||||
|
let root = driver.find(By::Css("[data-slhx-root]")).await?;
|
||||||
driver
|
driver
|
||||||
.execute(
|
.execute(
|
||||||
r#"
|
r#"
|
||||||
document.querySelector('[data-slhx-root]').insertAdjacentHTML('beforeend', `
|
const root = arguments[0];
|
||||||
<article id="probe-island" data-slhx-island="orbit" data-island-snapshot="1|1|1|probe waiting">
|
const island = document.createElement('article');
|
||||||
<canvas width="32" height="16"></canvas>
|
island.id = 'probe-island';
|
||||||
<p data-island-readout="">waiting</p>
|
island.setAttribute('data-slhx-island', 'orbit');
|
||||||
</article>
|
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(() => {
|
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);
|
}, 25);
|
||||||
return true;
|
return true;
|
||||||
"#,
|
"#,
|
||||||
Vec::new(),
|
vec![root.to_json()?],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn drag_card_to_lane(driver: &WebDriver, work_id: u64, lane: &str) -> WebDriverResult<()> {
|
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
|
driver
|
||||||
.execute(
|
.execute(
|
||||||
&format!(
|
|
||||||
r#"
|
r#"
|
||||||
const card = document.querySelector({:?});
|
const card = arguments[0];
|
||||||
const lane = document.querySelector({:?});
|
const lane = arguments[1];
|
||||||
const data = new DataTransfer();
|
const data = new DataTransfer();
|
||||||
card.dispatchEvent(new DragEvent('dragstart', {{ bubbles: true, dataTransfer: data }}));
|
card.dispatchEvent(new DragEvent('dragstart', { bubbles: true, dataTransfer: data }));
|
||||||
lane.dispatchEvent(new DragEvent('dragover', {{ bubbles: true, cancelable: 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 }}));
|
lane.dispatchEvent(new DragEvent('drop', { bubbles: true, cancelable: true, dataTransfer: data }));
|
||||||
return true;
|
return true;
|
||||||
"#,
|
"#,
|
||||||
format!(".work-card[data-key='{work_id}']"),
|
vec![card.to_json()?, lane.to_json()?],
|
||||||
format!(".lane[data-lane='{lane}']"),
|
|
||||||
),
|
|
||||||
Vec::new(),
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user