mirror of
https://github.com/velocitatem/PHANTOM.git
synced 2026-05-31 16:43:36 +00:00
164 lines
5.7 KiB
TypeScript
164 lines
5.7 KiB
TypeScript
import { test, expect } from '../fixtures';
|
|
import {
|
|
createFreshSession,
|
|
viewProductViaFlow,
|
|
rapidViewProductViaFlow,
|
|
humanLikeViewProduct,
|
|
getPriceFromDOM,
|
|
verifySessionConsistency,
|
|
addToCart,
|
|
} from '../helpers/interactions';
|
|
import { getSessionEvents } from '../helpers/kafka';
|
|
import { runSessionPricing } from '../helpers/airflow';
|
|
|
|
test.describe('SessionAwarePricer E2E', () => {
|
|
const STORE_TYPE = 'hotel';
|
|
|
|
test('baseline: human-like behavior maintains base price', async ({ page, backendUrl }) => {
|
|
const sessionId = await createFreshSession(page, STORE_TYPE);
|
|
|
|
const productId1 = await humanLikeViewProduct(page, STORE_TYPE);
|
|
const baselinePrice = await getPriceFromDOM(page);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
|
|
await page.waitForTimeout(1500);
|
|
|
|
const productId2 = await humanLikeViewProduct(page, STORE_TYPE);
|
|
|
|
await runSessionPricing(STORE_TYPE);
|
|
|
|
const secondPrice = await getPriceFromDOM(page);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
|
|
expect(Math.abs(secondPrice - baselinePrice) / baselinePrice).toBeLessThan(0.1);
|
|
});
|
|
|
|
test('agent detection: rapid robot-like behavior increases price', async ({ page, backendUrl }) => {
|
|
const sessionId = await createFreshSession(page, STORE_TYPE);
|
|
|
|
const productId = await viewProductViaFlow(page, STORE_TYPE);
|
|
const baselinePrice = await getPriceFromDOM(page);
|
|
|
|
await page.waitForTimeout(500);
|
|
|
|
await rapidViewProductViaFlow(page, 8, 100, STORE_TYPE);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
|
|
await page.waitForTimeout(1000);
|
|
|
|
const events = await getSessionEvents(backendUrl, sessionId);
|
|
expect(events.length).toBeGreaterThanOrEqual(8);
|
|
|
|
await runSessionPricing(STORE_TYPE);
|
|
|
|
await page.goto(`/products/${productId}`);
|
|
await page.waitForLoadState('networkidle');
|
|
const agentPrice = await getPriceFromDOM(page);
|
|
|
|
expect(agentPrice).toBeGreaterThan(baselinePrice);
|
|
expect((agentPrice - baselinePrice) / baselinePrice).toBeGreaterThan(0.01);
|
|
});
|
|
|
|
test('velocity threshold: high event rate triggers detection', async ({ page, backendUrl }) => {
|
|
const sessionId = await createFreshSession(page, STORE_TYPE);
|
|
|
|
const productId = await viewProductViaFlow(page, STORE_TYPE);
|
|
const baselinePrice = await getPriceFromDOM(page);
|
|
|
|
await rapidViewProductViaFlow(page, 10, 80, STORE_TYPE);
|
|
|
|
const events = await getSessionEvents(backendUrl, sessionId);
|
|
expect(events.length).toBeGreaterThanOrEqual(10);
|
|
|
|
await runSessionPricing(STORE_TYPE);
|
|
|
|
await page.goto(`/products/${productId}`);
|
|
await page.waitForLoadState('networkidle');
|
|
const agentPrice = await getPriceFromDOM(page);
|
|
|
|
expect(agentPrice).toBeGreaterThan(baselinePrice);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
});
|
|
|
|
test('cart ratio: high cart/view ratio signals intent', async ({ page, backendUrl }) => {
|
|
const sessionId = await createFreshSession(page, STORE_TYPE);
|
|
|
|
const productId = await viewProductViaFlow(page, STORE_TYPE);
|
|
const baselinePrice = await getPriceFromDOM(page);
|
|
|
|
await page.waitForTimeout(500);
|
|
await addToCart(page);
|
|
|
|
await page.waitForTimeout(2000);
|
|
|
|
await page.goto(`/products/${productId}`);
|
|
await page.waitForLoadState('networkidle');
|
|
const cartPrice = await getPriceFromDOM(page);
|
|
|
|
expect(cartPrice).toBeGreaterThanOrEqual(baselinePrice);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
});
|
|
|
|
test('mixed behavior: occasional fast actions tolerated', async ({ page, backendUrl }) => {
|
|
const sessionId = await createFreshSession(page, STORE_TYPE);
|
|
|
|
const productId1 = await humanLikeViewProduct(page, STORE_TYPE);
|
|
const baselinePrice = await getPriceFromDOM(page);
|
|
|
|
await page.waitForTimeout(1200);
|
|
|
|
await rapidViewProductViaFlow(page, 2, 150, STORE_TYPE);
|
|
|
|
await page.waitForTimeout(1000);
|
|
await humanLikeViewProduct(page, STORE_TYPE);
|
|
|
|
await runSessionPricing(STORE_TYPE);
|
|
|
|
const finalPrice = await getPriceFromDOM(page);
|
|
|
|
expect(Math.abs(finalPrice - baselinePrice) / baselinePrice).toBeLessThan(0.3);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
});
|
|
|
|
test('session isolation: agent behavior in one session does not affect others', async ({
|
|
page,
|
|
context,
|
|
backendUrl,
|
|
}) => {
|
|
const sessionIdA = await createFreshSession(page, STORE_TYPE);
|
|
const productId = await viewProductViaFlow(page, STORE_TYPE);
|
|
const basePrice = await getPriceFromDOM(page);
|
|
|
|
await rapidViewProductViaFlow(page, 10, 100, STORE_TYPE);
|
|
await page.waitForTimeout(2000);
|
|
|
|
await page.goto(`/products/${productId}`);
|
|
await page.waitForLoadState('networkidle');
|
|
const agentPrice = await getPriceFromDOM(page);
|
|
expect(agentPrice).toBeGreaterThan(basePrice * 0.99);
|
|
|
|
const page2 = await context.newPage();
|
|
const sessionIdB = await createFreshSession(page2, STORE_TYPE);
|
|
|
|
await page2.goto(`/products/${productId}`);
|
|
await page2.waitForLoadState('networkidle');
|
|
const cleanPrice = await getPriceFromDOM(page2);
|
|
|
|
expect(Math.abs(cleanPrice - basePrice) / basePrice).toBeLessThan(0.1);
|
|
expect(sessionIdA).not.toBe(sessionIdB);
|
|
});
|
|
|
|
test('session persistence: session ID maintained across views', async ({ page }) => {
|
|
const sessionId = await createFreshSession(page, STORE_TYPE);
|
|
|
|
await viewProductViaFlow(page, STORE_TYPE);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
|
|
await viewProductViaFlow(page, STORE_TYPE);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
|
|
await viewProductViaFlow(page, STORE_TYPE);
|
|
expect(await verifySessionConsistency(page, sessionId)).toBeTruthy();
|
|
});
|
|
});
|