HS reset/first/last: defaultValue tracking, list-of-elements reset, find().first|last
Mock DOM: - El now tracks defaultValue/defaultChecked/defaultSelected and a reset() method that walks descendant form controls, restoring them. - setAttribute(value|checked|selected) sets the matching default-* too, so the initial HTML state can be restored later. - parseHTMLFragments + _setInnerHTML capture a textarea's textContent as its value AND defaultValue. Generator (pw-body): - add_action / add_assertion extract .first() / .last() / .nth(N) modifiers into (nth (dom-query-all …) i) or a (let ((_all …)) (nth _all (- … 1))) tail so multi-match helpers hit the right element. Compiler: - emit-reset! with a .<class>/.<sel> query target now compiles to hs-query-all so 'reset .resettable' resets every matching control (not just the first). Net: reset 1→8 (100%).
This commit is contained in:
@@ -800,19 +800,24 @@ def parse_dev_body(body, elements, var_names):
|
||||
|
||||
def add_action(stmt):
|
||||
am = re.search(
|
||||
r"find\((['\"])(.+?)\1\)(?:\.(?:first|last)\(\)|\.nth\((\d+)\))?"
|
||||
r"find\((['\"])(.+?)\1\)(?:\.(first|last)\(\)|\.nth\((\d+)\))?"
|
||||
r"\.(click|dispatchEvent|fill|check|uncheck|focus|selectOption)\(([^)]*)\)",
|
||||
stmt,
|
||||
)
|
||||
if not am or 'expect' in stmt:
|
||||
return False
|
||||
selector = am.group(2)
|
||||
nth_idx = am.group(3)
|
||||
action_type = am.group(4)
|
||||
action_arg = am.group(5).strip("'\"")
|
||||
first_last = am.group(3)
|
||||
nth_idx = am.group(4)
|
||||
action_type = am.group(5)
|
||||
action_arg = am.group(6).strip("'\"")
|
||||
target = selector_to_sx(selector, elements, var_names)
|
||||
if nth_idx is not None:
|
||||
target = f'(nth (dom-query-all (dom-body) "{selector}") {nth_idx})'
|
||||
elif first_last == 'last':
|
||||
target = f'(let ((_all (dom-query-all (dom-body) "{selector}"))) (nth _all (- (len _all) 1)))'
|
||||
elif first_last == 'first':
|
||||
target = f'(nth (dom-query-all (dom-body) "{selector}") 0)'
|
||||
if action_type == 'click':
|
||||
ops.append(f'(dom-dispatch {target} "click" nil)')
|
||||
elif action_type == 'dispatchEvent':
|
||||
@@ -837,7 +842,7 @@ def parse_dev_body(body, elements, var_names):
|
||||
|
||||
def add_assertion(stmt):
|
||||
em = re.search(
|
||||
r"expect\(find\((['\"])(.+?)\1\)(?:\.(?:first|last)\(\)|\.nth\((\d+)\))?\)\.(not\.)?"
|
||||
r"expect\(find\((['\"])(.+?)\1\)(?:\.(first|last)\(\)|\.nth\((\d+)\))?\)\.(not\.)?"
|
||||
r"(toHaveText|toHaveClass|toHaveCSS|toHaveAttribute|toHaveValue|toBeVisible|toBeHidden|toBeChecked)"
|
||||
r"\(((?:[^()]|\([^()]*\))*)\)",
|
||||
stmt,
|
||||
@@ -845,13 +850,18 @@ def parse_dev_body(body, elements, var_names):
|
||||
if not em:
|
||||
return False
|
||||
selector = em.group(2)
|
||||
nth_idx = em.group(3)
|
||||
negated = bool(em.group(4))
|
||||
assert_type = em.group(5)
|
||||
args_str = em.group(6)
|
||||
first_last = em.group(3)
|
||||
nth_idx = em.group(4)
|
||||
negated = bool(em.group(5))
|
||||
assert_type = em.group(6)
|
||||
args_str = em.group(7)
|
||||
target = selector_to_sx(selector, elements, var_names)
|
||||
if nth_idx is not None:
|
||||
target = f'(nth (dom-query-all (dom-body) "{selector}") {nth_idx})'
|
||||
elif first_last == 'last':
|
||||
target = f'(let ((_all (dom-query-all (dom-body) "{selector}"))) (nth _all (- (len _all) 1)))'
|
||||
elif first_last == 'first':
|
||||
target = f'(nth (dom-query-all (dom-body) "{selector}") 0)'
|
||||
sx = pw_assertion_to_sx(target, negated, assert_type, args_str)
|
||||
if sx:
|
||||
ops.append(sx)
|
||||
|
||||
Reference in New Issue
Block a user