Skip to content

Migrate e2e test suite to Playwright TypeScript#237

Open
HusneShabbir wants to merge 2 commits into
redhat-ai-dev:mainfrom
HusneShabbir:test/migrate-e2e-to-playwright-ts
Open

Migrate e2e test suite to Playwright TypeScript#237
HusneShabbir wants to merge 2 commits into
redhat-ai-dev:mainfrom
HusneShabbir:test/migrate-e2e-to-playwright-ts

Conversation

@HusneShabbir

@HusneShabbir HusneShabbir commented Jul 6, 2026

Copy link
Copy Markdown

Summary

  • Replace the Python pytest-based UI test suite with Playwright TypeScript specs and shared test support utilities.
  • Update CI workflows, local test scripts, and testing docs to run the new Playwright-based automation path consistently.
  • Remove obsolete Python test scaffolding and add JSON upload fixtures used by notebook and lightspeed coverage.

Resolves:
https://redhat.atlassian.net/browse/RHIDP-15130

Replace the Python pytest UI test stack with Playwright TypeScript tests and update CI scripts/docs so local and CI runs execute the same test workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Migrate E2E suite to Playwright TypeScript (Node) and update CI/scripts

🧪 Tests ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Replace pytest-based Playwright tests with Playwright TypeScript specs and shared helpers.
• Update CI workflows and local scripts to install Node deps and run npx playwright test.
• Add JSON upload fixtures for Lightspeed and Notebook file-upload coverage.
Diagram

graph TD
  CI["GitHub Actions"] --> Scripts["scripts/run-tests.sh"] --> PW["Playwright runner"] --> Specs["TS specs"] --> Utils["support utils"] --> Auth["Keycloak impersonation"] --> RHDH["RHDH UI"]
  Specs --> Fix["upload fixtures"]
  subgraph Legend
    direction LR
    _ci["Pipeline"] ~~~ _sh["Shell script"] ~~~ _code["Test code"] ~~~ _ext{{"External system"}} ~~~ _data[("Fixtures")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Incremental migration (dual-run Python + TS temporarily)
  • ➕ Lower cutover risk; keep existing CI green while porting feature-by-feature
  • ➕ Easier to bisect regressions between harnesses
  • ➖ More CI time and maintenance overhead
  • ➖ Harder to keep parity between two suites
2. Use Playwright globalSetup + storageState for auth
  • ➕ Faster suite startup and fewer repeated Keycloak/admin calls
  • ➕ Centralizes auth logic and reduces per-spec boilerplate
  • ➖ Requires careful invalidation/refresh of stored state
  • ➖ Can hide auth regressions if state becomes too “static”
3. Keep Playwright but remain on Python (pytest-playwright)
  • ➕ Less rewrite; preserves existing team Python investment
  • ➕ Potentially smaller diff / faster initial merge
  • ➖ Diverges from broader TS/Node Playwright ecosystem conventions
  • ➖ Harder to share helpers/types with other TS-based test tooling

Recommendation: The PR’s full cutover to Playwright TypeScript is a solid long-term simplification (single Node toolchain, Playwright-native runner, shared typed helpers). Consider a follow-up to move auth into Playwright globalSetup + storageState once the suite stabilizes, to reduce Keycloak calls and speed up CI.

Files changed (38) +2473 / -49

Tests (28) +2352 / -0
de.upload1.jsonAdd German upload fixture (1) +5/-0

Add German upload fixture (1)

• Adds a small JSON file used to exercise locale-based upload scenarios and upload caps.

tests/fixtures/uploads/de.upload1.json

de.upload2.jsonAdd German upload fixture (2) +5/-0

Add German upload fixture (2)

• Adds a second German JSON upload fixture for multi-file/cap coverage.

tests/fixtures/uploads/de.upload2.json

en.upload1.jsonAdd English upload fixture (1) +5/-0

Add English upload fixture (1)

• Adds an English JSON upload fixture used by notebook upload flows.

tests/fixtures/uploads/en.upload1.json

en.upload2.jsonAdd English upload fixture (2) +5/-0

Add English upload fixture (2)

• Adds another English JSON upload fixture for additional upload cases.

tests/fixtures/uploads/en.upload2.json

es.upload1.jsonAdd Spanish upload fixture (1) +5/-0

Add Spanish upload fixture (1)

• Adds a Spanish JSON upload fixture for file-cap and locale coverage.

tests/fixtures/uploads/es.upload1.json

es.upload2.jsonAdd Spanish upload fixture (2) +5/-0

Add Spanish upload fixture (2)

• Adds a second Spanish JSON upload fixture used in upload batching/cap tests.

tests/fixtures/uploads/es.upload2.json

fr.upload1.jsonAdd French upload fixture (1) +5/-0

Add French upload fixture (1)

• Adds a French JSON upload fixture for multi-locale notebook upload tests.

tests/fixtures/uploads/fr.upload1.json

fr.upload2.jsonAdd French upload fixture (2) +5/-0

Add French upload fixture (2)

• Adds a second French JSON upload fixture for upload cap scenarios.

tests/fixtures/uploads/fr.upload2.json

it.upload1.jsonAdd Italian upload fixture (1) +5/-0

Add Italian upload fixture (1)

• Adds an Italian JSON upload fixture for notebook document upload coverage.

tests/fixtures/uploads/it.upload1.json

it.upload2.jsonAdd Italian upload fixture (2) +5/-0

Add Italian upload fixture (2)

• Adds a second Italian JSON upload fixture for upload cap and duplicate handling tests.

tests/fixtures/uploads/it.upload2.json

ja.upload1.jsonAdd Japanese upload fixture (1) +5/-0

Add Japanese upload fixture (1)

• Adds a Japanese JSON upload fixture to reach the 11-file staging cap test set.

tests/fixtures/uploads/ja.upload1.json

upload1.jsonAdd generic upload fixture (1) +4/-0

Add generic upload fixture (1)

• Adds a generic JSON fixture used by file attachment tests in Lightspeed chat.

tests/fixtures/uploads/upload1.json

upload2.jsonAdd generic upload fixture (2) +4/-0

Add generic upload fixture (2)

• Adds a second generic JSON fixture used for multi-file rejection scenarios.

tests/fixtures/uploads/upload2.json

lightspeed.spec.tsAdd Lightspeed E2E coverage in Playwright TypeScript +512/-0

Add Lightspeed E2E coverage in Playwright TypeScript

• Adds a comprehensive serial Lightspeed UI suite covering display modes, model selection, conversation flows, sidebar behavior, chat management actions, and file attachment validations. Uses shared support utilities and Keycloak impersonation login in a session-scoped context.

tests/specs/lightspeed.spec.ts

notebook.spec.tsAdd Notebook E2E coverage for Lightspeed notebooks +251/-0

Add Notebook E2E coverage for Lightspeed notebooks

• Introduces notebook-focused tests for fullscreen list empty state, create flows, upload modal behavior (duplicates, caps, unsupported types), sidebar interactions, rename/delete, and conversation+feedback within notebooks. Reuses shared helpers and the impersonation auth flow.

tests/specs/notebook.spec.ts

auth.tsImplement Keycloak impersonation login in TypeScript +196/-0

Implement Keycloak impersonation login in TypeScript

• Ports the Python auth flow to TS using Playwright request context: OIDC start, client-credentials token retrieval, user lookup, impersonation, and cookie parsing. Exposes a helper to inject cookies and complete the UI sign-in flow.

tests/support/auth.ts

chat-management.tsAdd shared helpers for chat history/pin/rename/sort flows +301/-0

Add shared helpers for chat history/pin/rename/sort flows

• Provides locator helpers and reusable actions/assertions for chat context menus, rename/pin/unpin/delete, pinned section toggling, search, and sort ordering checks. Encapsulates repeated UI mechanics used across Lightspeed tests.

tests/support/chat-management.ts

conversation-helper.tsAdd shared conversation helpers (send, stop, feedback, clipboard) +189/-0

Add shared conversation helpers (send, stop, feedback, clipboard)

• Adds utilities to send messages, wait for bot responses, verify response actions, submit feedback, and validate clipboard copy behavior via polling. Centralizes common conversation assertions used by multiple specs.

tests/support/conversation-helper.ts

file-upload.tsAdd file upload helpers and assertions +55/-0

Add file upload helpers and assertions

• Implements reusable upload routines for attachment input interactions plus validations for duplicates and unsupported file types. Includes a small visibility assertion helper for multi-locator state checks.

tests/support/file-upload.ts

lightspeed-page.tsAdd Lightspeed page helpers (modes, model, history drawer) +178/-0

Add Lightspeed page helpers (modes, model, history drawer)

• Encapsulates key Lightspeed UI operations: opening chatbot, selecting display mode/model, opening/closing history drawer, and asserting shell visibility per mode. Adds high-level expectations for empty history and conversation area baseline UI.

tests/support/lightspeed-page.ts

notebook-add-document-modal.tsAdd page object for notebook 'Add document' modal +78/-0

Add page object for notebook 'Add document' modal

• Introduces a small page object for the upload modal with helpers for file chooser interaction and staged-count assertions. Reduces duplication in notebook tests around modal behavior.

tests/support/notebook-add-document-modal.ts

notebook-constants.tsCentralize notebook constants and fixture-path utilities +41/-0

Centralize notebook constants and fixture-path utilities

• Defines key notebook URL/limits and helper functions to build upload fixture paths (including the 11-file cap set). Provides a single source of truth for notebook-related test constants.

tests/support/notebook-constants.ts

notebook-delete-dialog.tsAdd page object for notebook delete confirmation dialog +35/-0

Add page object for notebook delete confirmation dialog

• Adds a helper class to locate the correct delete dialog by notebook name and validate the permanent-deletion warning. Provides a single confirm action for reuse across tests.

tests/support/notebook-delete-dialog.ts

notebook-overwrite-confirm-modal.tsAdd page object for notebook overwrite confirmation modal +36/-0

Add page object for notebook overwrite confirmation modal

• Implements helpers to assert overwrite modal visibility/content and cancel behavior. Used to validate duplicate-upload prompting in notebook flows.

tests/support/notebook-overwrite-confirm-modal.ts

notebook-rename-modal.tsAdd page object for notebook rename dialog +35/-0

Add page object for notebook rename dialog

• Adds helpers to locate the rename modal by current name and submit a new displayed name. Used by notebook grid rename scenarios.

tests/support/notebook-rename-modal.ts

notebook-surface-page.tsAdd notebook surface page object for list/editor interactions +291/-0

Add notebook surface page object for list/editor interactions

• Introduces a higher-level page object covering notebooks tab navigation, empty state, editor onboarding assertions, document sidebar interactions, upload flows, and card overflow actions (rename/delete). Serves as the primary abstraction for notebook spec readability.

tests/support/notebook-surface-page.ts

sidebar.tsAdd helpers for Lightspeed chat drawer open/close assertions +74/-0

Add helpers for Lightspeed chat drawer open/close assertions

• Adds utilities to assert initial drawer state via ARIA snapshots and to open/close the chat history drawer across responsive layouts. Used by Lightspeed sidebar stability tests.

tests/support/sidebar.ts

test-helper.tsAdd shared navigation helper to open Lightspeed reliably +17/-0

Add shared navigation helper to open Lightspeed reliably

• Provides a single helper to navigate to /lightspeed and wait for any stable Lightspeed shell signal. Intended to reduce flakes by standardizing readiness checks.

tests/support/test-helper.ts

Documentation (3) +26 / -14
tester.mdUpdate tester agent instructions for Playwright TypeScript +10/-7

Update tester agent instructions for Playwright TypeScript

• Switches the test-runner guidance from pytest/uv to Node + Playwright TypeScript. Updates example commands for dependency install and running full/single tests.

.claude/agents/tester.md

CLAUDE.mdUpdate repo testing docs to reflect TS Playwright specs +4/-4

Update repo testing docs to reflect TS Playwright specs

• Updates testing section to Node/TypeScript requirements and points to primary spec files. Removes pytest marker documentation in favor of spec locations.

CLAUDE.md

TESTING.mdDocument Node-based Playwright E2E workflow +12/-3

Document Node-based Playwright E2E workflow

• Replaces Python/uv prerequisites with Node/npm requirements and adds a manual run snippet for Playwright. Updates troubleshooting language to reference the first authenticated Lightspeed spec flow.

docs/TESTING.md

Other (7) +95 / -35
ci-pr-check.yamlRun E2E in CI using Node/npm instead of Python/uv +7/-8

Run E2E in CI using Node/npm instead of Python/uv

• Replaces Python setup and 'uv sync' with Node setup, npm cache, and 'npm ci'. Updates Playwright browser install invocation to 'npx playwright install'.

.github/workflows/ci-pr-check.yaml

nightly.ymlMigrate nightly E2E workflow from pytest to Playwright TS +8/-9

Migrate nightly E2E workflow from pytest to Playwright TS

• Switches environment setup to Node with npm caching and installs deps via 'npm ci'. Runs the suite with 'npx playwright test' instead of 'uv run pytest'.

.github/workflows/nightly.yml

ci-run-tests.shAlign CI test args with Playwright runner +1/-1

Align CI test args with Playwright runner

• Replaces 'PYTEST_EXTRA_ARGS' with 'PLAYWRIGHT_EXTRA_ARGS' to cap failures in CI. Continues delegating execution to 'run-tests.sh'.

scripts/ci-run-tests.sh

run-tests.shSwitch test harness from uv/pytest to npm/Playwright +22/-17

Switch test harness from uv/pytest to npm/Playwright

• Adds strict bash mode, validates env vars more safely, and replaces virtualenv/pytest checks with Node/npm/package.json checks. Installs Node dependencies (ci vs install) and runs 'npx playwright test' with optional extra args.

scripts/run-tests.sh

package.jsonIntroduce Node test package for Playwright TypeScript +19/-0

Introduce Node test package for Playwright TypeScript

• Defines the tests package, Playwright/TypeScript devDependencies, and common scripts for local/CI runs. Establishes the Node toolchain for the E2E suite.

tests/package.json

playwright.config.tsAdd Playwright test runner configuration +25/-0

Add Playwright test runner configuration

• Configures test directory, timeouts, reporters, and execution settings (single worker/serial). Reads 'RHDH_BASE_URL' and 'PLAYWRIGHT_HEADLESS' to control runtime behavior.

tests/playwright.config.ts

tsconfig.jsonAdd TypeScript compiler config for E2E suite +13/-0

Add TypeScript compiler config for E2E suite

• Defines strict TS settings and includes specs/support/config files for typechecking. Aligns module settings with modern Node/ESM usage.

tests/tsconfig.json

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 4 rules

Grey Divider


Action required

1. Unquoted PLAYWRIGHT_EXTRA_ARGS expansion 📘 Rule violation ✧ Quality
Description
In scripts/run-tests.sh, PLAYWRIGHT_EXTRA_ARGS is expanded unquoted when invoking `npx
playwright test`, which will trigger ShellCheck SC2086 (word splitting/globbing) and violates the
requirement that scripts in scripts/ be ShellCheck-clean.
Code

scripts/run-tests.sh[92]

+  npx playwright test ${PLAYWRIGHT_EXTRA_ARGS:-}
Relevance

⭐⭐⭐ High

ShellCheck is enforced via workflow added in PR #80; team tends to keep scripts ShellCheck-clean.

PR-#80

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 902157 requires all shell scripts under scripts/ to be ShellCheck-clean (errors
and warnings). The modified line invokes npx playwright test with an unquoted variable expansion
(${PLAYWRIGHT_EXTRA_ARGS:-}), which triggers ShellCheck SC2086 unless refactored or explicitly
disabled with an adjacent justification comment.

Rule 902157: Shell scripts in scripts/ must be ShellCheck-clean
scripts/run-tests.sh[92-92]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`scripts/run-tests.sh` expands `PLAYWRIGHT_EXTRA_ARGS` unquoted (`${PLAYWRIGHT_EXTRA_ARGS:-}`), which will fail ShellCheck (SC2086) and violates the requirement that all `scripts/` shell scripts are ShellCheck-clean.

## Issue Context
The script intends to allow passing multiple Playwright CLI args via an env var. ShellCheck flags unquoted expansions unless a justified disable comment is provided or the code is refactored to safely pass arguments.

## Fix Focus Areas
- scripts/run-tests.sh[92-92]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Nonportable import.meta.dirname 🐞 Bug ☼ Reliability
Description
The Playwright suite builds fixture paths with import.meta.dirname, which can be undefined on part
of the documented Node.js >=20 support range and will crash before any tests execute. This affects
both Lightspeed specs and notebook helpers that resolve fixture files.
Code

tests/specs/lightspeed.spec.ts[R87-88]

+const fixturesDir = path.join(import.meta.dirname, "../fixtures/uploads");
+const e2eRoot = path.join(import.meta.dirname, "..");
Relevance

⭐⭐ Medium

No historical evidence found about import.meta.dirname portability or Node 20+ path patterns in
repo.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The suite explicitly documents Node >=20 support, while the new TS tests use import.meta.dirname
to construct paths; if that property is missing, path joining will throw before tests run.

docs/TESTING.md[15-16]
scripts/run-tests.sh[53-55]
tests/specs/lightspeed.spec.ts[87-88]
tests/support/notebook-constants.ts[7-31]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Playwright TS code uses `import.meta.dirname` to compute fixture paths. This property is not reliably available across the documented Node >=20 range, so the test process can fail during module evaluation.

### Issue Context
The repo documents Node >=20 for local runs, but the spec/helper files assume `import.meta.dirname` exists.

### Fix Focus Areas
- Replace `import.meta.dirname` usages with a portable `__dirname` derived from `import.meta.url` (e.g., `fileURLToPath` + `path.dirname`).

- tests/specs/lightspeed.spec.ts[87-88]
- tests/support/notebook-constants.ts[7-31]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Pinned chat locator unscoped 🐞 Bug ≡ Correctness
Description
pinnedChatItems() and recentChatItems() both return all <li> elements in the drawer, so
verifyChatPinned() can pass even when a chat is only present in the recent section. The
context-menu helpers also filter by text without narrowing to a single element, which can trigger
Playwright strict-mode failures if the same chat appears in multiple sections.
Code

tests/support/chat-management.ts[R7-17]

+function drawerListItems(page: Page): Locator {
+  return historyDrawer(page).locator("li");
+}
+
+export function pinnedChatItems(page: Page): Locator {
+  return drawerListItems(page);
+}
+
+export function recentChatItems(page: Page): Locator {
+  return drawerListItems(page);
+}
Relevance

⭐⭐ Medium

No historical evidence found for Playwright locator scoping/strict-mode guidance in this repo’s
reviews.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper functions currently return the same locator for pinned and recent lists, and
verifyChatPinned uses that locator—so it can match a non-pinned (recent) entry. The Lightspeed
spec depends on this assertion to validate pin persistence.

tests/support/chat-management.ts[7-17]
tests/support/chat-management.ts[30-45]
tests/support/chat-management.ts[104-108]
tests/specs/lightspeed.spec.ts[411-434]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Chat management helpers do not distinguish pinned vs recent chat lists, which can produce false-positive pin/unpin assertions. Additionally, context-menu open helpers may act on multiple matches, causing strict-mode failures.

### Issue Context
These helpers are used by `lightspeed.spec.ts` to validate pinning persistence and unpin behavior.

### Fix Focus Areas
- Implement `pinnedChatItems()` and `recentChatItems()` to scope to their respective sections/menus under the "Pinned chats" and "Chats" headings.
- In `openChatContextMenuByName` / `openPinnedChatContextMenuByName`, narrow to a single row (e.g., `.first()` or a more specific selector) before clicking Options.

- tests/support/chat-management.ts[3-17]
- tests/support/chat-management.ts[19-45]
- tests/support/chat-management.ts[104-108]
- tests/specs/lightspeed.spec.ts[411-434]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Duplicate npm install in CI 🐞 Bug ➹ Performance
Description
The PR-check workflow runs npm ci in tests/ and then calls make ci-tests, but
scripts/run-tests.sh unconditionally runs npm ci again, duplicating dependency installation
work. This increases CI runtime and adds an extra point of failure for every PR run.
Code

scripts/run-tests.sh[R76-82]

+log "Installing Node dependencies in $TESTS_DIR..."
+cd "$TESTS_DIR"
+if [ -f package-lock.json ]; then
+  npm ci
+else
+  npm install
+fi
Relevance

⭐⭐ Medium

No historical evidence on removing duplicate npm installs; recent CI work (PR #209) didn’t optimize
this.

PR-#209

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The CI PR workflow installs dependencies in tests/ before running make ci-tests, and `make
ci-tests runs scripts/run-tests.sh`, which repeats the install step.

.github/workflows/ci-pr-check.yaml[72-88]
Makefile[9-16]
scripts/ci-run-tests.sh[1-7]
scripts/run-tests.sh[76-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
CI installs test dependencies twice: once in the workflow and again inside `scripts/run-tests.sh`. This is redundant work and increases CI runtime/failure surface.

### Issue Context
`make ci-tests` executes `scripts/ci-run-tests.sh` which delegates to `scripts/run-tests.sh`.

### Fix Focus Areas
- Choose a single owner for dependency installation:
 - either remove the workflow `npm ci` step and keep install in `run-tests.sh` (but ensure Playwright browser install still has dependencies available), or
 - add a guard/flag in `run-tests.sh` to skip install when CI already ran it (e.g., `SKIP_NPM_INSTALL=1`).

- .github/workflows/ci-pr-check.yaml[72-88]
- Makefile[9-16]
- scripts/ci-run-tests.sh[1-7]
- scripts/run-tests.sh[76-82]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread scripts/run-tests.sh
KEYCLOAK_CLIENT_SECRET="$KEYCLOAK_CLIENT_SECRET" \
PLAYWRIGHT_HEADLESS="${PLAYWRIGHT_HEADLESS:-true}" \
uv run pytest -v "${PYTEST_EXTRA_ARGS:-}"
npx playwright test ${PLAYWRIGHT_EXTRA_ARGS:-}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Unquoted playwright_extra_args expansion 📘 Rule violation ✧ Quality

In scripts/run-tests.sh, PLAYWRIGHT_EXTRA_ARGS is expanded unquoted when invoking `npx
playwright test`, which will trigger ShellCheck SC2086 (word splitting/globbing) and violates the
requirement that scripts in scripts/ be ShellCheck-clean.
Agent Prompt
## Issue description
`scripts/run-tests.sh` expands `PLAYWRIGHT_EXTRA_ARGS` unquoted (`${PLAYWRIGHT_EXTRA_ARGS:-}`), which will fail ShellCheck (SC2086) and violates the requirement that all `scripts/` shell scripts are ShellCheck-clean.

## Issue Context
The script intends to allow passing multiple Playwright CLI args via an env var. ShellCheck flags unquoted expansions unless a justified disable comment is provided or the code is refactored to safely pass arguments.

## Fix Focus Areas
- scripts/run-tests.sh[92-92]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +87 to +88
const fixturesDir = path.join(import.meta.dirname, "../fixtures/uploads");
const e2eRoot = path.join(import.meta.dirname, "..");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Nonportable import.meta.dirname 🐞 Bug ☼ Reliability

The Playwright suite builds fixture paths with import.meta.dirname, which can be undefined on part
of the documented Node.js >=20 support range and will crash before any tests execute. This affects
both Lightspeed specs and notebook helpers that resolve fixture files.
Agent Prompt
### Issue description
The Playwright TS code uses `import.meta.dirname` to compute fixture paths. This property is not reliably available across the documented Node >=20 range, so the test process can fail during module evaluation.

### Issue Context
The repo documents Node >=20 for local runs, but the spec/helper files assume `import.meta.dirname` exists.

### Fix Focus Areas
- Replace `import.meta.dirname` usages with a portable `__dirname` derived from `import.meta.url` (e.g., `fileURLToPath` + `path.dirname`).

- tests/specs/lightspeed.spec.ts[87-88]
- tests/support/notebook-constants.ts[7-31]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +7 to +17
function drawerListItems(page: Page): Locator {
return historyDrawer(page).locator("li");
}

export function pinnedChatItems(page: Page): Locator {
return drawerListItems(page);
}

export function recentChatItems(page: Page): Locator {
return drawerListItems(page);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. Pinned chat locator unscoped 🐞 Bug ≡ Correctness

pinnedChatItems() and recentChatItems() both return all <li> elements in the drawer, so
verifyChatPinned() can pass even when a chat is only present in the recent section. The
context-menu helpers also filter by text without narrowing to a single element, which can trigger
Playwright strict-mode failures if the same chat appears in multiple sections.
Agent Prompt
### Issue description
Chat management helpers do not distinguish pinned vs recent chat lists, which can produce false-positive pin/unpin assertions. Additionally, context-menu open helpers may act on multiple matches, causing strict-mode failures.

### Issue Context
These helpers are used by `lightspeed.spec.ts` to validate pinning persistence and unpin behavior.

### Fix Focus Areas
- Implement `pinnedChatItems()` and `recentChatItems()` to scope to their respective sections/menus under the "Pinned chats" and "Chats" headings.
- In `openChatContextMenuByName` / `openPinnedChatContextMenuByName`, narrow to a single row (e.g., `.first()` or a more specific selector) before clicking Options.

- tests/support/chat-management.ts[3-17]
- tests/support/chat-management.ts[19-45]
- tests/support/chat-management.ts[104-108]
- tests/specs/lightspeed.spec.ts[411-434]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread scripts/run-tests.sh
Comment on lines +76 to +82
log "Installing Node dependencies in $TESTS_DIR..."
cd "$TESTS_DIR"
if [ -f package-lock.json ]; then
npm ci
else
npm install
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

4. Duplicate npm install in ci 🐞 Bug ➹ Performance

The PR-check workflow runs npm ci in tests/ and then calls make ci-tests, but
scripts/run-tests.sh unconditionally runs npm ci again, duplicating dependency installation
work. This increases CI runtime and adds an extra point of failure for every PR run.
Agent Prompt
### Issue description
CI installs test dependencies twice: once in the workflow and again inside `scripts/run-tests.sh`. This is redundant work and increases CI runtime/failure surface.

### Issue Context
`make ci-tests` executes `scripts/ci-run-tests.sh` which delegates to `scripts/run-tests.sh`.

### Fix Focus Areas
- Choose a single owner for dependency installation:
  - either remove the workflow `npm ci` step and keep install in `run-tests.sh` (but ensure Playwright browser install still has dependencies available), or
  - add a guard/flag in `run-tests.sh` to skip install when CI already ran it (e.g., `SKIP_NPM_INSTALL=1`).

- .github/workflows/ci-pr-check.yaml[72-88]
- Makefile[9-16]
- scripts/ci-run-tests.sh[1-7]
- scripts/run-tests.sh[76-82]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Cover single-server MCP toggle/edit/tool-call behavior and make notebook/lightspeed checks resilient to real cluster state differences.
Comment thread .claude/agents/tester.md
---

You are a test runner for the AI Rolling Demo E2E test suite. Tests live in `tests/` and use Playwright + pytest (Python ≥3.11, managed with `uv`).
You are a test runner for the AI Rolling Demo E2E test suite. Tests live in `tests/` and use Playwright + TypeScript (Node.js ≥20).

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.

package.json specifies Node.js 24 types as a development dependency, shouldn't this mean we'll need Node 24 or at least that?

Suggested change
You are a test runner for the AI Rolling Demo E2E test suite. Tests live in `tests/` and use Playwright + TypeScript (Node.js ≥20).
You are a test runner for the AI Rolling Demo E2E test suite. Tests live in `tests/` and use Playwright + TypeScript (Node.js ≥24).

Comment thread scripts/run-tests.sh
if [ ! -f "$VENV_ACTIVATE" ]; then
log_fail "Virtual environment not found at $TESTS_DIR/.venv. Run 'uv sync' inside tests/ first."
if ! command -v node >/dev/null 2>&1; then
log_fail "Node.js is not installed. Install Node.js 20+ and retry."

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.

Same as previous comment:

Suggested change
log_fail "Node.js is not installed. Install Node.js 20+ and retry."
log_fail "Node.js is not installed. Install Node.js 24+ and retry."

Comment thread CLAUDE.md
## Testing

Tests are in `tests/` using Playwright + pytest (Python ≥3.11, managed with `uv`).
Tests are in `tests/` using Playwright + TypeScript (Node.js ≥20).

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.

Same as previous comment:

Suggested change
Tests are in `tests/` using Playwright + TypeScript (Node.js ≥20).
Tests are in `tests/` using Playwright + TypeScript (Node.js ≥24).

Comment thread .claude/agents/tester.md
---

You are a test runner for the AI Rolling Demo E2E test suite. Tests live in `tests/` and use Playwright + pytest (Python ≥3.11, managed with `uv`).
You are a test runner for the AI Rolling Demo E2E test suite. Tests live in `tests/` and use Playwright + TypeScript (Node.js ≥20).

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.

Should we merge this to development first before the main branch? cc @michael-valdron

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.

Ah good catch @maysunfaisal! Yes, we should re-target this PR to development branch instead of main.

fyi @HusneShabbir

await dropdown.click();
await expect(page.locator("body")).toMatchAriaSnapshot(`
- menu:
- menuitem "gpt-4.1-mini"

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.

This will break whenever models are added or removed from the deployment. Consider asserting that at least one model menu item is visible rather than matching an exact snapshot, or document that this test must be updated when models change.

Comment thread tests/specs/mcp.spec.ts
Comment on lines +27 to +39
test.beforeAll(async ({ browser }) => {
test.setTimeout(12 * 60 * 1000);

context = await browser.newContext({
baseURL: process.env.RHDH_BASE_URL,
permissions: ["clipboard-read", "clipboard-write"],
ignoreHTTPSErrors: true,
locale: "en-US",
timezoneId: "UTC",
userAgent:
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 " +
"(KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
});

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.

copy-pasted identically across lightspeed.spec.ts, mcp.spec.ts, and notebook.spec.ts. Consider extracting into a shared fixture.

await uploadModal.clickAddFilesForStagedCount(1);
await expect(uploadModal.dialog()).toBeHidden();
await notebooks.expectDocumentUploadCompletes(fileName);
await page.waitForTimeout(5000);

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.

Agentic Claude:

Consider replacing with a waitFor on the expected UI state to avoid flakiness

@michael-valdron michael-valdron 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.

@HusneShabbir Failures are happening because this is coming from a forked repository, workflows seem to only run correctly if the PR branch is in this repository.

cc @thepetk

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.

3 participants