Skip to content

Migrated RulesEngine DOM action functional tests to Vitest+Playwright+MSW#1550

Open
carterworks wants to merge 3 commits into
migrate-integration/00-infrafrom
migrate-integration/18-rules-engine
Open

Migrated RulesEngine DOM action functional tests to Vitest+Playwright+MSW#1550
carterworks wants to merge 3 commits into
migrate-integration/00-infrafrom
migrate-integration/18-rules-engine

Conversation

@carterworks

@carterworks carterworks commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Changed Packages

  • core
  • reactor-extension

Description

Migrates the RulesEngine DOM action functional tests to the new Vitest+Playwright+MSW harness. New mock fixture rulesEngineEvaluateResponse.json added (condition matches ~type=rulesEngine for the evaluateRulesets path).

Related Issue

Part of the functional test → integration test migration. See packages/browser/test/FUNCTIONAL_MIGRATION_PLAN.md.

Motivation and Context

The existing TestCafe functional test suite is being migrated to Vitest+Playwright+MSW to enable faster, more reliable CI testing without a running server. This PR is part of a stacked series — each PR migrates one test file.

Functional tests replaced:

  • packages/browser/test/functional/specs/RulesEngine/C13348429.js
  • packages/browser/test/functional/specs/RulesEngine/C13405889.js
  • packages/browser/test/functional/specs/RulesEngine/C13419240.js

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (non-breaking change which does not add functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have added a Changeset file with a consumer-facing description of my changes.
  • I have signed the Adobe Open Source CLA or I'm an Adobe employee.
  • I have made any necessary test changes and all tests pass.
  • I have run the Sandbox successfully.

Stack

  1. Migrated Install SDK functional tests to Vitest+Playwright+MSW #1533
  2. Added MSW handlers, mock fixtures, and Vitest+Playwright test harness for functional test migration #1532
  3. Migrated RulesEngine DOM action functional tests to Vitest+Playwright+MSW #1550 👈 current

@carterworks carterworks added the ignore-for-release Do not include this PR in release notes label Jun 12, 2026
@carterworks carterworks self-assigned this Jun 12, 2026
@changeset-bot

changeset-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 61a65a0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@greptile-apps

greptile-apps Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a new Vitest+Playwright+MSW integration spec (rulesEngine.spec.js) that replaces three previously-skipped TestCafe functional tests for RulesEngine DOM actions, covering sendEvent, applyResponse, and evaluateRulesets paths with fully mocked network responses.

  • C13419240 intercepts sendEvent via MSW's inAppMessageHandler and asserts that the in-app message container is rendered into the DOM.
  • C13348429 passes inAppMessageResponse inline to applyResponse (bypassing the network) and asserts the same DOM outcome.
  • C13405889 stores a ruleset via applyResponse with renderDecisions: false, then triggers client-side evaluation with evaluateRulesets, asserting the ruleset's ~type=rulesEngine condition fires the DOM action.

Confidence Score: 3/5

The spec is safe to merge as a test-only change, but the missing DOM cleanup between tests means C13348429 and C13405889 may be asserting against stale DOM state from the prior test rather than verifying their own command's rendering.

The three tests run sequentially in the same browser page. cleanAlloy() tears down the Alloy instance but leaves injected DOM nodes (#alloy-messaging-container, #alloy-overlay-container) in place. Tests 2 and 3 call document.getElementById("alloy-messaging-container") immediately after their respective alloy commands; if that element was already inserted by the preceding test, both the toBeInTheDocument() and innerHTML assertions pass trivially regardless of whether applyResponse or evaluateRulesets actually rendered anything. The same repo's inapp_messages.spec.js removes these nodes explicitly for exactly this reason.

packages/browser/test/integration/specs/RulesEngine/rulesEngine.spec.js — all three test bodies need end-of-test DOM teardown matching the pattern in inapp_messages.spec.js

Important Files Changed

Filename Overview
packages/browser/test/integration/specs/RulesEngine/rulesEngine.spec.js New integration spec migrating three TestCafe RulesEngine tests; missing DOM cleanup between tests risks false-positive assertions in C13348429 and C13405889, and configure is not awaited in C13419240.

Sequence Diagram

sequenceDiagram
    participant T as Test
    participant A as Alloy (browser)
    participant MSW as MSW Worker
    participant DOM as Browser DOM

    note over T,DOM: C13419240 — sendEvent path
    T->>A: configure(alloyConfig)
    T->>MSW: worker.use(inAppMessageHandler)
    T->>A: "sendEvent({renderDecisions:true, surfaces:[…]})"
    A->>MSW: POST /v1/interact
    MSW-->>A: "inAppMessageResponse.json (ruleset-item ~type=edge)"
    A->>A: "evaluate ruleset (condition: ~type=edge ✓)"
    A->>DOM: "inject #alloy-messaging-container + alloy-content-iframe"
    T->>DOM: getElementById(alloy-messaging-container)
    T->>T: assert toBeInTheDocument + innerHTML contains iframe

    note over T,DOM: C13348429 — applyResponse path
    T->>A: configure(alloyConfig)
    T->>A: "applyResponse({renderDecisions:true, responseBody: inAppMessageResponse})"
    A->>A: "evaluate ruleset (condition: ~type=edge ✓)"
    A->>DOM: "inject #alloy-messaging-container + alloy-content-iframe"
    T->>DOM: getElementById(alloy-messaging-container)
    T->>T: assert toBeInTheDocument + innerHTML contains iframe

    note over T,DOM: C13405889 — evaluateRulesets path
    T->>A: configure(alloyConfig)
    T->>A: "applyResponse({renderDecisions:false, responseBody: rulesEngineEvaluateResponse})"
    A->>A: "store ruleset (condition: ~type=rulesEngine), no render"
    T->>A: "evaluateRulesets({renderDecisions:true, decisionContext:{user:alloy}})"
    A->>A: "evaluate ruleset (condition: ~type=rulesEngine ✓)"
    A->>DOM: "inject #alloy-messaging-container + alloy-content-iframe"
    T->>DOM: getElementById(alloy-messaging-container)
    T->>T: assert toBeInTheDocument + innerHTML contains iframe
Loading

Reviews (1): Last reviewed commit: "test(integration): migrate rules engine ..." | Re-trigger Greptile

Comment on lines +33 to +37
});

const container = document.getElementById("alloy-messaging-container");
await expect.element(container).toBeInTheDocument();
expect(container.innerHTML).toContain("alloy-content-iframe");

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.

P1 Missing DOM cleanup between tests

cleanAlloy() (called by the alloy fixture between tests) removes the Alloy instance but does not remove DOM nodes created by Alloy's rendering (e.g., #alloy-messaging-container, #alloy-overlay-container, #alloy-content-iframe). Running three tests in sequence means C13348429 and C13405889 both find these elements already present in the DOM from C13419240, so their document.getElementById and expect.element(container).toBeInTheDocument() assertions pass trivially even if applyResponse/evaluateRulesets never rendered anything.

The established pattern in this repo (see inapp_messages.spec.js lines 38–43) is to explicitly remove the injected containers at the end of each test. All three tests here should do the same.

Comment on lines +20 to +22
// onBeforeEvent sets ~type="com.adobe.eventType.edge" → inAppMessageResponse condition matches
test("C13419240 - Verify DOM action using the sendEvent command", async ({
alloy,

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 configure is not awaited

In C13419240, alloy("configure", alloyConfig) is called without await before alloy("sendEvent", ...) is awaited. If configure has not resolved (e.g., identity-acquire response is slow to return even in bypass mode), the sendEvent call queued behind it could race. Compare inapp_messages.spec.js line 22 which has the same omission — but this PR is a good opportunity to harden the pattern with await alloy("configure", alloyConfig).

Comment on lines +57 to +70
test("C13405889 - Verify DOM action using the evaluateRulesets command", async ({
alloy,
}) => {
await alloy("configure", alloyConfig);

await alloy("applyResponse", {
renderDecisions: false,
responseBody: rulesEngineEvaluateResponse,
});

await alloy("evaluateRulesets", {
renderDecisions: true,
personalization: {
decisionContext: { user: "alloy" },

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 Missing network handler for the evaluateRulesets test

C13405889 calls configure without adding any MSW handler. On configure, Alloy may fire an identity-acquire request (/v1/identity/acquire). With onUnhandledRequest: "bypass", this falls through to the real network. In strict CI (no outbound network) the acquire call will fail, which could prevent Alloy from completing initialization. Adding acquireHandler via worker.use(acquireHandler) (already exported from handlers.js) before configure would make the test fully self-contained and resilient to network conditions.

@greptile-apps greptile-apps 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.

carterworks has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@carterworks carterworks force-pushed the migrate-integration/17-brand-concierge branch from bd82fca to 663fb81 Compare June 12, 2026 17:56
@carterworks carterworks force-pushed the migrate-integration/18-rules-engine branch from 4793858 to 90fa13b Compare June 12, 2026 17:57

@greptile-apps greptile-apps 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.

carterworks has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@carterworks carterworks changed the base branch from migrate-integration/17-brand-concierge to migrate-integration/00-infra June 12, 2026 17:57

@greptile-apps greptile-apps 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.

carterworks has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@carterworks carterworks force-pushed the migrate-integration/18-rules-engine branch 4 times, most recently from 69eb3dd to bace201 Compare June 12, 2026 21:20
@carterworks carterworks marked this pull request as draft June 15, 2026 16:38
@carterworks carterworks force-pushed the migrate-integration/18-rules-engine branch from bace201 to 2006893 Compare June 15, 2026 19:59
@carterworks carterworks marked this pull request as ready for review June 26, 2026 19:29
@carterworks carterworks force-pushed the migrate-integration/18-rules-engine branch from 07cc6ec to dff13ca Compare June 26, 2026 20:32
@carterworks carterworks force-pushed the migrate-integration/18-rules-engine branch 2 times, most recently from 79b7443 to c479108 Compare July 10, 2026 15:43
Keep the original testcafe functional specs alongside the new
Vitest+Playwright+MSW integration suite until these migration branches
merge, so reviewers retain the pre-migration signal.
@carterworks carterworks force-pushed the migrate-integration/18-rules-engine branch from c479108 to 61a65a0 Compare July 10, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ignore-for-release Do not include this PR in release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant