Files
pxil-selenium-automation/PLAYWRIGHT_MIGRATION.md

9.2 KiB

Playwright migration review

Preserved Selenium baseline

  • Reviewed on 2026-09-08; working tree was clean before this document was added.
  • Current branch: development.
  • Backup branch: backup/selenium-working-2026-09-08, created locally and pushed to origin.
  • Baseline commit: 4749efe45f47587e6d6aec228a4818576cb666d9.
  • HEAD, the local backup, and its remote-tracking reference were verified to match.
  • The backup preserves tracked source, configuration, and committed input files. Ignored virtual environments and generated reports are not included.
  • No browser tests were executed during this review; working behavior is the user's reported baseline.

To return to the baseline, first commit or stash any migration changes, then use:

git switch backup/selenium-working-2026-09-08

Keep the backup branch unchanged. Start implementation on a separate branch such as migration/playwright-python, created from development.

Keep Python, pytest, pytest-html, existing markers, and JSON/Excel inputs. Use Playwright's synchronous Python API with the official pytest-playwright plugin. This retains the existing business logic and test runner while changing the browser layer. A TypeScript rewrite would also require porting the data readers, configuration, and reporting, without a demonstrated need here.

Start with headed Chromium because exchange and trading-member logins currently require manual CAPTCHA input. Select a compatible dependency set, verify it in a separate virtual environment, and pin the validated versions. Install Chromium through Playwright as well as installing the Python packages.

References: installation, pytest fixtures and options.

Repository-specific changes

Existing area Recommended migration
tests/browser.py, tests/conftest.py Replace driver creation with plugin-managed browser/context/page fixtures for migrated tests. Keep Selenium's driver fixture while both suites coexist. Start with one isolated context per test.
tests/step_actions.py, tests/reporting.py Preserve step names and report metadata; use page.screenshot(path=...). Adapt the failure hook, which currently only looks for driver. Add failure traces and include their paths in reports.
tests/helpers.py, tests/regression/auth.py Port setup, exchange, trading-member, and MCO login separately. Wait for a successful authenticated page. Replace fixed CAPTCHA sleep with a bounded wait for manual entry and then verify login. Playwright does not remove the CAPTCHA requirement.
tests/locators.py, trading_locators.py Keep stable IDs initially. Convert Selenium By tuples into Playwright locators. Scope broad XPath matches to the active form, modal, or grid to avoid ambiguous matches.
tests/regression/ui_helpers.py Rewrite Bootstrap and Select2 interactions around the visible dropdown and exact option. Select2 is a custom widget; native select_option() is appropriate only for actual select elements. Preserve code-to-label matching deliberately.
bidding/grid_actions.py Port the existing Handsontable integration through page.evaluate() if needed. Separate waiting for the instance from mutating it. Validate the complete matrix and submitted outcome; the present helper only checks the first displayed value after populating.
bidding/upload_actions.py, folder_upload_actions.py, block_bulk_upload_actions.py Use set_input_files() for file inputs; use directory input support where the actual element supports directory selection. Preserve progress, per-file status, logs, and failure handling. Register expected confirmation-dialog handling before the triggering action.
matching/actions.py Replace CDP download configuration and directory polling with an expect_download() block around the export action, then save the download with the existing source-specific naming convention. Preserve business-status polling and timeouts.
matching/bid_transfer_actions.py Preserve request/status correlation and explicit rejection handling. Browser action readiness is not proof of successful bid transfer.
tests/regression/config_reader.py, tests/config_reader.py, input manifests, JSON/Excel readers Reuse browser-independent logic. Keep configuration schema and defaults stable during initial migration.
tests/file_generation.py Retain payload-generation logic and audit its separate dependency requirements when preparing the new environment.

Playwright auto-waits for action readiness and offers retrying assertions. Replace UI sleeps with visible/enabled/value/status assertions, but retain intentional business polling intervals. Avoid routinely replacing JavaScript click fallbacks with forced clicks; inspect overlays and locator scope first.

References: auto-waiting, inputs and uploads, downloads.

Parallel upload design

test_idas_exchange_bidding_flow.py currently creates separate Chrome drivers in ThreadPoolExecutor workers and synchronizes each batch with a Barrier. It also assigns accounts per TM and staggers logins.

First establish sequential Playwright upload parity. Do not share a Playwright instance, browser, context, or page across those threads: the Python API is not thread-safe. If retaining threads temporarily, each worker must create and close its own Playwright instance and browser.

For independent scenarios, consider pytest-xdist processes with separate accounts and data. For coordinated uploads that must begin together, use a dedicated async orchestration flow with separate contexts and an async barrier/event mechanism; ordinary test parallelism does not preserve the existing start barrier. Keep the rest of the suite synchronous. Preserve barrier cancellation when a worker fails.

Before concurrency, replace the current scan-and-increment report run numbering with collision-resistant run/worker identifiers. Preserve account-to-TM assignment and validate server-side session restrictions; browser-context isolation alone does not prevent account conflicts.

Reference: Python library threading guidance.

Suggested implementation sequence

  1. Create the migration branch and an isolated Playwright environment. Add a separate tests/playwright/ tree with scoped fixtures and explicit run commands so migration tests are not accidentally executed alongside the old suite. Keep shared data utilities browser-independent.
  2. Port test_idas_mco_login.py as the small pilot: credentials, navigation, dashboard assertion, screenshot reporting, and failure trace. Then port exchange and trading-member login with their manual CAPTCHA steps.
  3. Port session creation, token activation, and combined setup. Preserve configuration-controlled skips and verify the created session/token state rather than relying on screenshots alone. Root session/token test files are skip-only compatibility stubs; migrate the implementations under tests/setup/.
  4. Port one single-bid flow, including Select2 filters, market-specific input matrix, submission, and observable success. Then cover each configured market and both login roles.
  5. Port individual file upload, batch upload, folder upload, and block bulk upload sequentially. Compare file counts, progress completion, statuses, and generated logs against the Selenium behavior.
  6. Port transfer and matching. Preserve rejection-stop behavior, provisional matching checks, flow generation, and exported files for Green, Conventional, and HPDAM. Validate downloaded content as well as file presence.
  7. Add parallel upload support using the design above. Verify distinct sessions, coordinated start if required, failure cleanup, and distinct artifacts.
  8. Revisit fake-activity/manual-run utilities, update RUN_COMMANDS.md, and remove Selenium dependencies only after required flows pass. Order-book, trade-book, and reports directories contain scaffolding; define new coverage separately from migration parity.

During coexistence, run each suite using explicit paths. Preserve the existing combined-setup behavior; do not assume pytest test ordering will create prerequisites. Avoid automatic retries for state-changing bid/session/matching actions unless duplicate submissions are handled.

Completion criteria

  • Validate both implementations against controlled equivalent test data; running each against the same mutable state back-to-back can itself change the result.
  • Confirm session/token state, submitted bid data, upload success and failure outcomes, transfer rejection behavior, matching status, and downloaded content.
  • Confirm screenshots, logs, failure traces, manual CAPTCHA flow, and browser cleanup.
  • Require repeatable passing runs for every required configured flow before making Playwright the default.
  • Keep generated authentication state and traces out of Git; these can contain login/session data. Preserve the frozen backup without editing its historical configuration.

This document is a migration proposal. No Selenium implementation or dependency files have been changed.