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(())
}