Skip to content

feat(page-controller): reject misused actions and verify input results - #718

Open
gaomeng1900 wants to merge 3 commits into
mainfrom
feat/page-controller-action-guards
Open

gaomeng1900 wants to merge 3 commits into
mainfrom
feat/page-controller-action-guards

Conversation

@gaomeng1900

@gaomeng1900 gaomeng1900 commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

What

click / input_text on a native <select>, and input_text on non-text inputs (checkbox, radio, file, buttons), now fail instead of silently doing nothing. input_text on <input>/<textarea> and select_dropdown_option fail when the page discards the value; a reformatted value (input masks, normalizers) is still a success. Contenteditable behavior is unchanged.

Type

  • Breaking change
  • Bug fix
  • Feature / Improvement
  • Refactor / Chores
  • Documentation / Website / Demo / Testing

Testing

  • npm run ci passes
  • Tested in modern browsers
  • Types/doc added

Requirements / 要求

  • I have read and follow the Code of Conduct and Contributing Guide . / 我已阅读并遵守行为准则。
  • This PR is NOT generated by a bot or AI agent acting autonomously. I have authored or meaningfully reviewed every change. / 此 PR 不是由 bot 或 AI 自主生成的,我已亲自编写或充分审查了每一处变更。

Copilot AI lite review requested due to automatic review settings September 8, 2026 18:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new “discarded input” detection can incorrectly throw when the page reformats input back to a value the element already contained, which conflicts with the intended “reformatted is OK” behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR improves @page-agent/page-controller action reliability by rejecting unsupported interactions (e.g., clicking native <select>, typing into non-text inputs) and by verifying that text input and option selection actually “stick” after dispatching events.

Changes:

  • Add actionable rejections for misused actions (native <select> click; input_text on non-text input types / <select>).
  • Make input_text return and surface the post-input value (including masked/reformatted values), and treat discarded input as an error.
  • Make select_dropdown_option select via selectedIndex, dispatch input + change, and verify the final selection; add unit tests for these behaviors.
File summaries
File Description
packages/page-controller/src/PageController.ts Uses the returned post-input value to add a warning when the page reformats user input.
packages/page-controller/src/actions.ts Enforces invalid-action rejection and adds post-action verification for input and select operations.
packages/page-controller/src/actions.test.ts Adds Vitest coverage for the new rejection and verification behaviors.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/page-controller/src/actions.ts Outdated
Comment on lines +280 to +288
const textAfter = readText(element)
const matches = textAfter.trim() === text.trim()
const discarded = textAfter === textBefore || textAfter.trim() === ''
if (!matches && discarded) {
throw new Error(
`The page discarded the input. The element now contains ${JSON.stringify(textAfter)}. Inspect the current page state before retrying.`
)
}
return textAfter
Comment on lines +281 to +284
const note =
actualText.trim() === text.trim()
? ''
: ` ⚠️ The page changed it; the element now contains (${actualText}).`

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3dd98f40e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/page-controller/src/actions.ts Outdated
await waitFor(0.1)

const textAfter = readText(element)
const matches = textAfter.trim() === text.trim()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve whitespace when verifying input results

When a caller intentionally enters leading/trailing whitespace—or only whitespace—and the page normalizes it away, this trimmed comparison treats the requested and actual values as equal. In the whitespace-only case, an input listener that resets " " to "" bypasses the discard check, and PageController.inputText repeats the trimmed comparison, returning an unqualified success even though the field is empty. Compare exact values for verification and only normalize where the input contract explicitly permits it.

AGENTS.md reference: AGENTS.md:L151-L152

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-10T18:19:44.252719Z b7ba6eb New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@gaomeng1900
gaomeng1900 force-pushed the feat/page-controller-action-guards branch from d3dd98f to bb5238e Compare September 10, 2026 15:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bb5238e572

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/page-controller/src/actions.ts Outdated
Comment on lines +267 to +270
// Pages may legitimately reformat the value (masks, normalizers), so a different value
// is not a failure. An unchanged or emptied field means the page discarded the input.
const value = input.value
if (value !== text && (value === valueBefore || value === '')) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return reformatted values to the caller

When an input mask or listener converts the requested text into a different non-empty value, this branch intentionally treats the operation as successful, but inputTextElement returns no value and PageController.inputText still reports the original text at lines 281-284. The agent therefore receives a misleading success message and cannot inspect the actual page state; return the observed value so the wrapper can report the transformation.

AGENTS.md reference: AGENTS.md:L151-L152

Useful? React with 👍 / 👎.

@gaomeng1900
gaomeng1900 force-pushed the feat/page-controller-action-guards branch from bb5238e to c0f0b4e Compare September 10, 2026 16:53
@gaomeng1900

Copy link
Copy Markdown
Collaborator Author

Reproduced on IMask’s phone demo: inputting 79991234567 twice correctly retains +7(999)123-45-67, but the second call throws “The page discarded the input.” Main succeeds.

Please keep the action-type guards. For text input, briefly report the requested and actual values when they differ, without failing the action: an unchanged formatted value does not prove rejection.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f4f0fb010

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


await waitFor(0.1) // Wait to ensure change event processing completes

if (selectElement.selectedIndex !== option.index) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify against the current selected option

When an input or change handler rebuilds the options while preserving the requested choice, option refers to the removed node and its live index no longer represents the replacement option's position. This check can therefore throw “discarded” even though the current select still contains and selects the requested option; verify the current selectedOptions using stable expected text/value instead of the original node's index.

AGENTS.md reference: AGENTS.md:L151-L152

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b7ba6eb6f1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


await waitFor(0.1)

return input.value

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject reads from inputs replaced by event handlers

When a synchronous input handler replaces this element, dispatchEvent completes after the replacement, but this line still reads the detached input. PageController.inputText can therefore report the requested value as a successful current value while the live replacement is empty or normalized differently; detect a disconnected element and fail or resolve the live indexed element before reporting its value.

AGENTS.md reference: AGENTS.md:L151-L152

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants