rstudio-migrate-tests-selenium-to-playwright

star 5.0k

Migrate Python Selenium/Selene electron tests to TypeScript/Playwright. Use when converting tests from rstudio-ide-automation/rstudio_server_pro/electron-tests/ to rstudio/e2e/rstudio/tests/.

rstudio By rstudio schedule Updated 6/5/2026

name: rstudio-migrate-tests-selenium-to-playwright description: Migrate Python Selenium/Selene electron tests to TypeScript/Playwright. Use when converting tests from rstudio-ide-automation/rstudio_server_pro/electron-tests/ to rstudio/e2e/rstudio/tests/.

Migrate Electron Tests to Playwright

Converts Python test files from rstudio-ide-automation/rstudio_server_pro/electron-tests/ to TypeScript/Playwright tests in rstudio/e2e/rstudio/tests/.

Arguments

The user provides one or more targets:

  • A single file: /rstudio-migrate-tests-selenium-to-playwright test_desktop_console.py
  • A directory: /rstudio-migrate-tests-selenium-to-playwright GlobalPrefs/
  • A keyword: /rstudio-migrate-tests-selenium-to-playwright citations

Hard Rules

  1. Load skills and the README first — Before doing any conversion work, always: (a) load rstudio-create-playwright-tests; (b) read e2e/rstudio/README.md in full, the suite's primary reference (read it fresh for each migration; don't assume it was read earlier in the session); (c) load rstudio-run-playwright-tests, whose run protocol governs the verification in Hard Rule 5.
  2. Check MIGRATION_FROM_SELENIUM_PROGRESS.md — Before starting, verify the file hasn't already been converted or partially converted. Located at e2e/rstudio/docs/MIGRATION_FROM_SELENIUM_PROGRESS.md.
  3. Tests must work on Desktop and Server, and on Windows, macOS, and Linux — Use the unified fixture (@fixtures/rstudio.fixture). Don't hardcode Desktop-only or OS-specific patterns; use cross-platform shortcuts (ControlOrMeta where appropriate) and process.platform guards, or tag mode/OS-specific tests (@desktop_only, @windows_only, etc.).
  4. No Claude dependency — All test infrastructure must be runnable from terminal, CI, and GitHub Actions. Claude subagents are a convenience layer, not a requirement.
  5. A test isn't migrated until it passes. Run the converted TypeScript test against a live RStudio instance (Desktop or Server, depending on target). Retry up to 3 times. If it still fails, mark it test.fixme() with a blocker note and track it as Fixme in MIGRATION_FROM_SELENIUM_PROGRESS.md. Do not list a fixme test as migrated in summaries, PR descriptions, or progress tracking.

Steps

Step 1: Resolve the target

  • Search for the file under electron-tests/
  • Read the full Python source — understand test methods, fixtures, imports, page objects
  • Check e2e/rstudio/docs/MIGRATION_FROM_SELENIUM_PROGRESS.md for current status

Step 2: Read reference materials

  • Load rstudio-create-playwright-tests skill
  • Read e2e/rstudio/README.md in full -- the suite's primary reference; read it fresh for each migration, don't assume it was read earlier in the session
  • Load rstudio-run-playwright-tests skill -- its run protocol governs the verification gate (Hard Rule 5)
  • Check rstudio-ide-automation/rstudio_server_pro/electron-tests/ for other Selenium/Selene electron tests covering the same functionality — useful for test logic, assertions, and expected values
  • Check rstudio-ide-automation/rstudio_server_pro/tests/ for Selenium/Selene server tests covering the same functionality — useful for test logic, assertions, and expected values
  • Check rstudio-pro/e2e/ for Workbench e2e patterns (examples include .or() locator chaining, clickIfVisible() helpers, input fill with retry, reload-on-hang recovery) -- look for anything else reusable
  • Read relevant existing Playwright page objects in e2e/rstudio/pages/
  • Read relevant existing Playwright actions in e2e/rstudio/actions/
  • Read relevant existing Playwright test specs in e2e/rstudio/tests/ -- BRAT is retired; anything that was in BRAT is now in the Playwright suite

For large files or batch migrations: if the source has many methods (say 10+) or you're migrating a directory, consider launching a general-purpose subagent to analyze the Python source(s) and return a brief covering: test methods to convert, pytest markers / skip reasons, fixtures used, page objects referenced, parallel safety hints, and any unusual patterns. This keeps the main context lean for the writing and running phases. For typical single-file migrations with a handful of methods, do the analysis inline.

Step 3: Determine the target location

Map the electron-test to the Playwright directory structure:

Electron Location Playwright Location
Root-level console/terminal tests tests/panes/console/
EditorPane/ tests tests/panes/editor/
GlobalPrefs/ tests tests/panes/preferences/
Licensing/ tests tests/licensing/
Projects/ tests tests/projects/
Cross-pane tests (autocomplete, etc.) tests/panes/misc/

Use judgment — the Playwright structure is organized by function, not by the electron-tests layout.

Step 4: Write the TypeScript test

Follow the rules in the rstudio-create-playwright-tests skill (already loaded per Hard Rule 1). That skill covers imports, selector hierarchy, idiomatic patterns, parallel safety, package dependencies, cross-platform considerations, Ace/NES patterns, and CDP setup.

Migration-specific guidance:

  • Use test.fixme() for tests that can't pass yet -- never comment out or omit.

  • If the Selenium source has multiple near-identical methods, consider data-driven restructuring (one forEach loop) in the Playwright version.

  • When the Python source has @pytest.mark.skip or pytest.skip():

    1. Read the skip reason. Check if any linked issue is still open.
    2. If the reason is Selenium-specific, stale, or resolved → write the test like any other and verify it passes.
    3. If the reason still applies (open RStudio bug, missing feature) → test.fixme() with the reason / URL preserved as a comment directly above:
      // @skip: https://github.com/rstudio/rstudio/issues/12345
      test.fixme("test name", async () => {});
      
      If the Python skip has only a reason string (no URL), preserve the string verbatim. If the Python source has bare @skip with no reason, write // @skip: no reason given in Python source.

    Don't auto-fixme based on the marker alone.

Step 5: Add missing page objects or actions

If the test needs locators or methods not yet available:

  • Add locators to the appropriate file in pages/
  • Add interaction methods to the appropriate file in actions/
  • Follow existing patterns in those files

Step 6: Run the test

Hard gate (Hard Rule 5): a test doesn't count as migrated until it passes here.

Defer to the rstudio-run-playwright-tests skill for the canonical run commands (Desktop and Server). Present the command and wait for user approval before executing.

Quick reference for Desktop:

cd e2e/rstudio && npx playwright test tests/<path>/<file>.test.ts

If the test fails:

  • Review error output
  • Fix and re-run (up to 3 attempts)
  • If still failing, use test.fixme() for the failing test and note the blocker

Step 7: Reevaluate

After the test passes, review for:

  1. Code clarity — Remove unnecessary variables, simplify patterns, ensure descriptive test names
  2. Idiomatic patterns — Check against the list in Step 4
  3. Selector quality — Check against the hierarchy in Step 4
  4. Playwright + TypeScript conventions — Verify the code follows standard Playwright and TypeScript conventions (e.g., proper async/await usage, correct type annotations, Playwright's built-in assertions over manual checks, proper use of lifecycle hooks, no floating promises). Consult official Playwright docs and TypeScript best practices if uncertain.
  5. Duplication — Could any new helpers be shared via actions classes?

Present proposed improvements to the user. Only apply if approved. Re-run after changes.

Step 8: Update progress tracking

Two records to update -- the progress doc (this repo) and the migrated marker on the Selenium source (the rstudio-ide-automation repo).

Progress doc -- edit e2e/rstudio/docs/MIGRATION_FROM_SELENIUM_PROGRESS.md:

  • Update the file's status (Complete, Partial, or Fixme)
  • Add the Playwright target path and test count
  • Add notes if relevant
  • Add any fixme tests to the Fixme Tests table with blocker description

Mark the Selenium source as migrated -- in rstudio-ide-automation, add @pytest.mark.migratedToTypeScript so the Python suite records which tests are ported. Follow that repo's migrate-test skill, Step 15:

  • Mark each individual test method that passed verification. Never mark at the class level -- a class may be only partially migrated, and class-level marking would wrongly imply every method is done.
  • Module-level pytestmark = [pytest.mark.migratedToTypeScript, ...] is acceptable only when the file has no class and every method passed.
  • Never mark a method that ended up test.fixme() in Playwright.
  • This is a separate repo, so it needs its own test/ron/ branch, commit, and PR -- don't fold it into the rstudio PR.

Step 9: Commit and submit

Each substep requires explicit approval before proceeding. Ron may stop at any point -- not every migration goes all the way to merge.

9.1 Check branch. Run git branch --show-current, report the branch, ask Ron to confirm. Branch prefix for Playwright migration work: test/ron/ (e.g., test/ron/migrate-debugger). Kebab-case for the descriptive part. Never commit directly to main.

9.2 Review changes. Run git fetch origin. Determine the base branch -- never assume main. Check git log --oneline or ask. For short-lived solo test/ron/... branches, defer the base-branch merge to 9.5. Run git status (never -uall), git diff, git log --oneline -5. Summarize what changed. Flag anything that shouldn't be committed (secrets, scratch files, unrelated changes).

9.3 Stage and commit. Stage specific files by name (never git add -A). Draft a commit message focused on the "why" -- concise, single line preferred, uppercase first letter, no Co-Authored-By. Show the message, wait for approval. Commit, then git status.

9.4 Push. Show the push command, wait for approval, push with -u. Never push to main directly.

9.5 Create PR. If origin/<base> has moved since the last sync, propose git merge origin/<base> and wait for approval before running; then push the merge commit. Draft PR title (under 70 chars) and summary. Summary only -- no "Test plan" section, no AI attribution. Ask about reviewers; aliases: Kevin → kevinushey, Gary → gtritchie, JonV → jonvanausdeln, AT → astayleraz. Show full PR details, wait for approval. Create with gh pr create (use --reviewer if specified). Add the automation label. Return the PR URL.

9.6 Merge (only if Ron asks to merge this session). Check and report source + target branches, confirm both, wait for approval, merge.

9.7 Branch cleanup (only after merge). Offer to delete the local branch, wait for explicit approval.

Style throughout: never - (space-hyphen-space) -- use -- or em dash, no spaces. Never use #N numbering in GitHub comments (auto-links to wrong issues) -- use 1., (1), or Finding 1.

Step 10: Roborev review and assessment

Invoke the roborev-review skill on the commit to request a code review.

When findings come back, assess them before presenting to Ron:

  • Read each finding in the actual code context
  • Verify the finding is real and not a false positive
  • Judge real severity; don't blindly trust roborev's label, and don't overstate
  • Note any findings you'd skip and why

Present the assessed findings with recommendations. Wait for approval before editing any files. Severity policy:

  • Fix High and Medium findings
  • Fix Low findings only if they're real bugs or silent failures
  • Skip cosmetic Lows and "add tests for simple scripts" suggestions

Apply fixes manually. Do not invoke roborev-fix -- Ron prefers manual fixes through the migration flow. Re-run the test (Hard Rule 5 still applies). Commit per Step 9. Re-run roborev-review on the new commit. Repeat until no actionable findings remain.

Close reviewed findings via the roborev-respond skill once they're addressed.

Compact Instructions

If context compacts mid-migration, preserve:

  • Source and target paths for each file being migrated
  • Per-method status: which methods passed Step 6, which ended up test.fixme() and why
  • Page object / action additions made during the migration (so they're not duplicated)
  • Open roborev findings in progress: job ID, finding being fixed, severity assessment
  • Open blockers flagged for Ron (issues to file, upstream bugs found)

If a step has been completed, that fact also survives -- don't redo work Ron has already approved.

Server Mode Parallelism

Tests can run against multiple RStudio Server instances in parallel. This works from terminal, CI, or Claude subagents.

Targeting a server:

PW_RSTUDIO_SERVER_URL=https://server1:80 \
  npx playwright test tests/panes/misc/autocomplete.test.ts --project=server

Parallel execution (5 servers): Each process gets its own PW_RSTUDIO_SERVER_URL — no shared config files, no conflicts:

# Terminal / CI / shell script
PW_RSTUDIO_SERVER_URL=https://server1:80 npx playwright test tests/file1.test.ts --project=server &
PW_RSTUDIO_SERVER_URL=https://server2:80 npx playwright test tests/file2.test.ts --project=server &
PW_RSTUDIO_SERVER_URL=https://server3:80 npx playwright test tests/file3.test.ts --project=server &
wait

Claude subagent execution: Same commands, but each Agent tool call targets a different server with run_in_background: true. Results are collected and aggregated by the parent agent.

Desktop mode is unaffected — it doesn't use PW_RSTUDIO_SERVER_URL. The env var is only read by the server fixture path.

Output

After conversion, summarize:

  • Source file and methods converted
  • Playwright target file and location
  • Page objects or actions added/modified
  • Test results (passed/fixme with blockers)
  • Improvements made during reevaluation
  • MIGRATION_FROM_SELENIUM_PROGRESS.md updates
Install via CLI
npx skills add https://github.com/rstudio/rstudio --skill rstudio-migrate-tests-selenium-to-playwright
Repository Details
star Stars 5,014
call_split Forks 1,178
navigation Branch main
article Path SKILL.md
More from Creator