browser_tester 1.5.0

Deterministic lightweight browser runtime for Rust tests
Documentation
use super::*;

#[test]
fn element_get_bounding_client_rect_returns_dom_rect_like_object() -> Result<()> {
    let html = r#"
        <div id='box' style='width: 120px; height: 90px;'></div>
        <button id='run'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const box = document.getElementById('box');
            const rect = box.getBoundingClientRect();
            document.getElementById('result').textContent = [
              typeof rect === 'object',
              rect.x,
              rect.y,
              rect.left,
              rect.top,
              rect.right,
              rect.bottom,
              rect.width,
              rect.height,
              rect.right === rect.left + rect.width,
              rect.bottom === rect.top + rect.height
            ].join(':');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text("#result", "true:0:0:0:0:0:0:0:0:true:true")?;
    Ok(())
}

#[test]
fn element_get_bounding_client_rect_reflects_document_scroll_offset() -> Result<()> {
    let html = r#"
        <div id='box'></div>
        <button id='run'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const box = document.getElementById('box');
            box.scrollTo(25, 40);
            const rect = box.getBoundingClientRect();
            document.getElementById('result').textContent = [
              rect.left,
              rect.top,
              rect.x,
              rect.y,
              rect.right,
              rect.bottom
            ].join(':');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text("#result", "-25:-40:-25:-40:-25:-40")?;
    Ok(())
}

#[test]
fn element_get_bounding_client_rect_rejects_arguments() -> Result<()> {
    let html = r#"
        <div id='box'></div>
        <button id='run'>run</button>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            document.getElementById('box').getBoundingClientRect(1);
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    match h.click("#run") {
        Err(Error::ScriptRuntime(message)) => {
            assert!(
                message.contains("getBoundingClientRect takes no arguments"),
                "unexpected runtime error message: {message}"
            );
        }
        other => panic!("expected runtime error, got: {other:?}"),
    }
    Ok(())
}

#[test]
fn element_get_bounding_client_rect_exposes_branded_readonly_dom_rect_surface() -> Result<()> {
    let html = r#"
        <div id='box' style='width: 120px; height: 90px;'></div>
        <button id='run'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const rect = document.getElementById('box').getBoundingClientRect();
            const desc = Object.getOwnPropertyDescriptor(rect, 'x');
            rect.x = 9;
            const deleted = delete rect.x;
            document.getElementById('result').textContent = [
              Object.prototype.toString.call(rect),
              desc.writable,
              desc.configurable,
              rect.x,
              deleted,
              rect.x
            ].join(':');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text("#result", "[object DOMRect]:false:false:0:false:0")?;
    Ok(())
}

#[test]
fn reduced_dom_rect_surface_has_branded_readonly_non_copying_contract_work() -> Result<()> {
    let html = r#"
        <div id='box' style='width: 120px; height: 90px;'></div>
        <button id='run'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const rect = document.getElementById('box').getBoundingClientRect();
            const own = Object.getOwnPropertyNames(rect).sort().join(',');
            const copied = Object.keys(Object.assign({}, rect)).join(',');
            const spread = Object.keys({ ...rect }).join(',');
            document.getElementById('result').textContent = [
              Object.prototype.toString.call(rect),
              own,
              copied,
              spread,
              String(Object.getOwnPropertyDescriptor(rect, 'x').enumerable),
              String(Object.getOwnPropertyDescriptor(rect, 'width').writable)
            ].join('|');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text(
        "#result",
        "[object DOMRect]|bottom,height,left,right,top,width,x,y|||false|false",
    )?;
    Ok(())
}