browser_tester 1.5.0

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

#[test]
fn input_implicit_roles_for_common_types_and_list_variants_work() -> Result<()> {
    let html = r#"
        <datalist id='opts'>
          <option value='one'></option>
        </datalist>
        <input id='default'>
        <input id='text' type='text'>
        <input id='text-list' type='text' list='opts'>
        <input id='search' type='search'>
        <input id='search-list' type='search' list='opts'>
        <input id='email' type='email'>
        <input id='email-list' type='email' list='opts'>
        <input id='tel' type='tel'>
        <input id='tel-list' type='tel' list='opts'>
        <input id='url' type='url'>
        <input id='url-list' type='url' list='opts'>
        <input id='number' type='number'>
        <input id='checkbox' type='checkbox'>
        <input id='radio' type='radio'>
        <input id='range' type='range'>
        <input id='button' type='button'>
        <input id='submit' type='submit'>
        <input id='reset' type='reset'>
        <input id='image' type='image' alt='go' src='/go.png'>
        <input id='hidden' type='hidden'>
        <input id='password' type='password'>
        <button id='run' type='button'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const ids = [
              'default', 'text', 'text-list', 'search', 'search-list',
              'email', 'email-list', 'tel', 'tel-list', 'url', 'url-list',
              'number', 'checkbox', 'radio', 'range', 'button', 'submit',
              'reset', 'image', 'hidden', 'password'
            ];
            document.getElementById('result').textContent =
              ids.map((id) => document.getElementById(id).role).join(':');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text(
        "#result",
        "textbox:textbox:combobox:searchbox:combobox:textbox:combobox:textbox:combobox:textbox:combobox:spinbutton:checkbox:radio:slider:button:button:button:button::",
    )?;
    Ok(())
}

#[test]
fn input_role_reacts_to_type_list_changes_and_explicit_override_roundtrip() -> Result<()> {
    let html = r#"
        <datalist id='opts'>
          <option value='two'></option>
        </datalist>
        <input id='target' type='text'>
        <button id='run' type='button'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const target = document.getElementById('target');
            const initial = target.role;

            target.setAttribute('list', 'opts');
            const withList = target.role;

            target.removeAttribute('list');
            const withoutList = target.role;

            target.type = 'number';
            const numberRole = target.role;

            target.type = 'checkbox';
            const checkboxRole = target.role;

            target.role = 'switch';
            const assigned = target.role + ':' + target.getAttribute('role');

            target.removeAttribute('role');
            const restored = target.role + ':' + (target.getAttribute('role') === null);

            document.getElementById('result').textContent =
              initial + '|' +
              withList + '|' +
              withoutList + '|' +
              numberRole + '|' +
              checkboxRole + '|' +
              assigned + '|' +
              restored;
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text(
        "#result",
        "textbox|combobox|textbox|spinbutton|checkbox|switch:switch|checkbox:true",
    )?;
    Ok(())
}

#[test]
fn input_interface_properties_reflect_form_labels_and_multiple_state() -> Result<()> {
    let html = r#"
        <form id='account-form'></form>
        <label id='email-label' for='email'>Email</label>
        <input id='email' name='email' type='email' form='account-form' multiple required>
        <input id='upload' type='file' multiple>
        <input id='note' type='text'>
        <button id='run' type='button'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const email = document.getElementById('email');
            const labels = email.labels;
            const upload = document.getElementById('upload');
            const note = document.getElementById('note');

            document.getElementById('result').textContent = [
              email.form.id,
              labels.length,
              labels.item(0).id,
              email.multiple,
              upload.multiple,
              note.multiple,
              email.name,
              email.required,
              email.type
            ].join(':');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text(
        "#result",
        "account-form:1:email-label:true:true:false:email:true:email",
    )?;
    Ok(())
}

#[test]
fn input_multiple_property_assignment_reflects_attribute() -> Result<()> {
    let html = r#"
        <input id='email' type='email' multiple>
        <input id='plain' type='text'>
        <button id='run' type='button'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const email = document.getElementById('email');
            const plain = document.getElementById('plain');

            const before = email.multiple + ':' + email.hasAttribute('multiple') + ':' +
              plain.multiple + ':' + plain.hasAttribute('multiple');

            email.multiple = false;
            const middle = email.multiple + ':' + email.hasAttribute('multiple');

            plain.multiple = true;
            const after = plain.multiple + ':' + plain.hasAttribute('multiple');

            document.getElementById('result').textContent =
              before + '|' + middle + '|' + after;
          });
        </script>
        "#;

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

#[test]
fn input_default_value_and_default_checked_dirty_sync_work() -> Result<()> {
    let html = r#"
        <form id='prefs'>
          <input id='name' value='seed'>
          <input id='agree' type='checkbox'>
          <input id='r1' type='radio' name='plan' checked>
          <input id='r2' type='radio' name='plan'>
        </form>
        <button id='run' type='button'>run</button>
        <p id='result'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const form = document.getElementById('prefs');
            const name = document.getElementById('name');
            const agree = document.getElementById('agree');
            const r1 = document.getElementById('r1');
            const r2 = document.getElementById('r2');

            name.defaultValue = 'base';
            agree.defaultChecked = true;
            r2.defaultChecked = true;
            const clean = [
              name.defaultValue,
              name.value,
              name.getAttribute('value'),
              String(agree.defaultChecked),
              String(agree.checked),
              String(r1.defaultChecked),
              String(r1.checked),
              String(r2.defaultChecked),
              String(r2.checked)
            ].join(':');

            name.value = 'dirty';
            agree.checked = false;
            r1.checked = true;
            name.defaultValue = 'later';
            agree.defaultChecked = true;
            r1.defaultChecked = false;
            r2.defaultChecked = true;
            const dirty = [
              name.defaultValue,
              name.value,
              name.getAttribute('value'),
              String(agree.defaultChecked),
              String(agree.checked),
              String(r1.defaultChecked),
              String(r1.checked),
              String(r2.defaultChecked),
              String(r2.checked)
            ].join(':');

            form.reset();
            const reset = [
              name.defaultValue,
              name.value,
              String(agree.checked),
              String(r1.checked),
              String(r2.checked)
            ].join(':');

            document.getElementById('result').textContent =
              [clean, dirty, reset].join('|');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text(
        "#result",
        "base:base:base:true:true:true:false:true:true|later:dirty:later:true:false:false:true:true:false|later:later:true:false:true",
    )?;
    Ok(())
}