Skip to content

Add salesforce domain skill: Setup permission sets (Lightning + classic iframe) - #531

Open
goxl-wtf wants to merge 1 commit into
browser-use:mainfrom
goxl-wtf:salesforce-setup-permission-sets
Open

goxl-wtf wants to merge 1 commit into
browser-use:mainfrom
goxl-wtf:salesforce-setup-permission-sets

Conversation

@goxl-wtf

@goxl-wtf goxl-wtf commented Jul 16, 2026

Copy link
Copy Markdown

Field-tested notes from automating permission-set creation/FLS/assignment in a Lightning Enterprise org via CDP:

  • /lightning/setup/PermSets/home 404s on some orgs; the classic address-wrapper route (PermissionSetListView/page?address=%2F0PS) always works
  • the classic setup iframe is same-origin but hidden behind nested shadow roots (top-level querySelectorAll('iframe') finds nothing) — includes a reusable shadow-walk snippet, plus the stale-frame-after-navigation trap
  • classic button quirks (padded input values, a.btn edit links), field-permission row targeting via fls_read_ck/fls_edit_ck ids
  • Aura forceVirtualCheckbox rows ignore JS .click() — compositor-click the faux span at its getBoundingClientRect() center
  • CDP clicks are CSS pixels, not screenshot pixels (HiDPI trap)
  • person-account FLS (PersonEmail) is controlled via Contact → Email, not the Accounts field list

No pixel coordinates, no org-specific data.

🤖 Generated with Claude Code


Summary by cubic

Adds a field-tested guide for automating Salesforce permission set setup in Lightning and classic-in-iframe. Focuses on reliable navigation, element targeting, and HiDPI-safe clicks to avoid pixel-based selectors.

  • New Features
    • Canonical Lightning/classic address-wrapper URLs for permission sets and object settings, plus guidance for “Page not found” vs missing perms.
    • Shadow DOM traversal to find the same-origin classic setup iframe and a reminder to re-find it after every navigation.
    • Stable selectors and behaviors in classic: padded button values, a.btn links, FLS row targeting, and proper input/change events.
    • Handling Aura virtual checkboxes with compositor clicks on the faux span and verifying selection state before continuing.
    • HiDPI-safe clicks via getBoundingClientRect(), PersonAccount FLS controlled under Contact → Email, and operational traps (re-login after profile changes, auth wall on login).

Written for commit 1a419ae. Summary will update on new commits.

Review in cubic

@browser-harness-review

Copy link
Copy Markdown

✅ Skill review passed

Reviewed 1 file(s) — no findings.

@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: 1a419ae1ca

ℹ️ 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 on lines +71 to +72
pos = js("(() => { const r = document.querySelector('...faux-selector...').getBoundingClientRect(); return JSON.stringify({x: r.x + r.width/2, y: r.y + r.height/2}); })()")
click(pos["x"], pos["y"]) # CSS pixels — see below

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 Parse the coordinate payload before indexing it

When users follow this Aura-checkbox snippet, js() returns the raw Runtime.evaluate value, so the JSON.stringify(...) result on the previous line is a Python string, not a dict. Indexing it with pos["x"] therefore raises TypeError: string indices must be integers before the compositor click can happen; either return a plain JS object from js() or wrap the result in json.loads(...) before calling click.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai Bot 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.

3 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="domain-skills/salesforce/setup-permission-sets.md">

<violation number="1" location="domain-skills/salesforce/setup-permission-sets.md:1">
P2: Adding this document directly bypasses the repository's skill-generation workflow, so the harness can overwrite it or reject it as an invalid skill artifact. The content should be emitted by the harness rather than maintained as a hand-authored skill file.</violation>

<violation number="2" location="domain-skills/salesforce/setup-permission-sets.md:39">
P2: On pages with more than one accessible iframe, this selects the wrong document, so later `contentDocument` queries can miss the setup controls. Filtering by a classic-page URL/DOM marker or returning candidates for caller-side disambiguation would make the walker reliable.</violation>

<violation number="3" location="domain-skills/salesforce/setup-permission-sets.md:72">
P2: The coordinate example raises a Python `TypeError` when `pos["x"]` is evaluated because `pos` is a JSON string, unless the harness adds an undocumented parse step. Returning the object directly from `js()` or parsing `pos` with `json.loads` before indexing keeps the example executable.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

@@ -0,0 +1,101 @@
# Salesforce Setup — permission sets (Lightning + classic-in-iframe)

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

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.

P2: Adding this document directly bypasses the repository's skill-generation workflow, so the harness can overwrite it or reject it as an invalid skill artifact. The content should be emitted by the harness rather than maintained as a hand-authored skill file.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At domain-skills/salesforce/setup-permission-sets.md, line 1:

<comment>Adding this document directly bypasses the repository's skill-generation workflow, so the harness can overwrite it or reject it as an invalid skill artifact. The content should be emitted by the harness rather than maintained as a hand-authored skill file.</comment>

<file context>
@@ -0,0 +1,101 @@
+# Salesforce Setup — permission sets (Lightning + classic-in-iframe)
+
+Field-tested on a Lightning Enterprise org with the enhanced setup domain
</file context>
Fix with cubic


```python
pos = js("(() => { const r = document.querySelector('...faux-selector...').getBoundingClientRect(); return JSON.stringify({x: r.x + r.width/2, y: r.y + r.height/2}); })()")
click(pos["x"], pos["y"]) # CSS pixels — see below

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

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.

P2: The coordinate example raises a Python TypeError when pos["x"] is evaluated because pos is a JSON string, unless the harness adds an undocumented parse step. Returning the object directly from js() or parsing pos with json.loads before indexing keeps the example executable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At domain-skills/salesforce/setup-permission-sets.md, line 72:

<comment>The coordinate example raises a Python `TypeError` when `pos["x"]` is evaluated because `pos` is a JSON string, unless the harness adds an undocumented parse step. Returning the object directly from `js()` or parsing `pos` with `json.loads` before indexing keeps the example executable.</comment>

<file context>
@@ -0,0 +1,101 @@
+
+```python
+pos = js("(() => { const r = document.querySelector('...faux-selector...').getBoundingClientRect(); return JSON.stringify({x: r.x + r.width/2, y: r.y + r.height/2}); })()")
+click(pos["x"], pos["y"])   # CSS pixels — see below
+```
+
</file context>
Fix with cubic

}
};
walk(document, 0);
window.__sfFrame = frames[0]; // re-find after EVERY navigation — it is replaced

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

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.

P2: On pages with more than one accessible iframe, this selects the wrong document, so later contentDocument queries can miss the setup controls. Filtering by a classic-page URL/DOM marker or returning candidates for caller-side disambiguation would make the walker reliable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At domain-skills/salesforce/setup-permission-sets.md, line 39:

<comment>On pages with more than one accessible iframe, this selects the wrong document, so later `contentDocument` queries can miss the setup controls. Filtering by a classic-page URL/DOM marker or returning candidates for caller-side disambiguation would make the walker reliable.</comment>

<file context>
@@ -0,0 +1,101 @@
+    }
+  };
+  walk(document, 0);
+  window.__sfFrame = frames[0];   // re-find after EVERY navigation — it is replaced
+  return frames.length;
+})()"""
</file context>
Fix with cubic

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.

1 participant