docs(leads): document Leads store migration and payment UI fix; note tests update
This commit is contained in:
162
tests/leads_payment.test.ts
Normal file
162
tests/leads_payment.test.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { testing_event_id } from './_helpers/env';
|
||||
import {
|
||||
testing_exhibit_id,
|
||||
exhibit_staff_passcode,
|
||||
setup_leads_test_page,
|
||||
} from './_helpers/leads_helpers';
|
||||
|
||||
const event_id = testing_event_id;
|
||||
const exhibit_id = testing_exhibit_id;
|
||||
const exhibit_url = `/events/${event_id}/leads/exhibit/${exhibit_id}`;
|
||||
|
||||
const signed_in_kv = { [exhibit_id]: { key: exhibit_staff_passcode, type: 'shared' } };
|
||||
|
||||
/** Locator for the CreditCard header button (Payment & Upgrades). */
|
||||
const payment_btn = (page: Parameters<typeof expect>[0]) =>
|
||||
(page as import('@playwright/test').Page).locator(
|
||||
'header button[title="Payment & Upgrades"]'
|
||||
);
|
||||
|
||||
/** Locator for the Manage / Settings header button. */
|
||||
const manage_btn = (page: Parameters<typeof expect>[0]) =>
|
||||
(page as import('@playwright/test').Page).locator(
|
||||
'header button[title="Manage Exhibit"]'
|
||||
);
|
||||
|
||||
test.describe('Leads — Payment Gate (leads_require_payment)', () => {
|
||||
// -----------------------------------------------------------------------
|
||||
// 1. leads_require_payment = false → no CreditCard button in header
|
||||
//
|
||||
// When the event-level flag is disabled the payment tab is not surfaced
|
||||
// at all — the button must be absent so exhibitors cannot accidentally
|
||||
// navigate to the Stripe flow when the event organiser covers costs.
|
||||
// -----------------------------------------------------------------------
|
||||
test('payment not required: CreditCard button absent from header', async ({ page }) => {
|
||||
await setup_leads_test_page(page, event_id, exhibit_id, {
|
||||
auth_kv: signed_in_kv,
|
||||
event_data_overrides: {
|
||||
mod_exhibits_json: { leads_require_payment: false },
|
||||
},
|
||||
});
|
||||
|
||||
await page.goto(exhibit_url);
|
||||
|
||||
// Wait for the event GET to complete so we know liveQuery has fired
|
||||
await page.waitForResponse(
|
||||
(r) => r.url().includes(`crud/event/${event_id}`) && r.status() === 200,
|
||||
{ timeout: 8_000 }
|
||||
);
|
||||
|
||||
// CreditCard button must remain absent after the event has loaded
|
||||
await expect(payment_btn(page)).not.toBeVisible({ timeout: 3_000 });
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 2. leads_require_payment = true → CreditCard button visible in header
|
||||
//
|
||||
// Default mock event has leads_require_payment: true — button must appear
|
||||
// once the event record is written to Dexie and lq__event_obj fires.
|
||||
// -----------------------------------------------------------------------
|
||||
test('payment required: CreditCard button visible in header', async ({ page }) => {
|
||||
await setup_leads_test_page(page, event_id, exhibit_id, {
|
||||
auth_kv: signed_in_kv,
|
||||
// Default mock event already has leads_require_payment: true
|
||||
});
|
||||
|
||||
await page.goto(exhibit_url);
|
||||
|
||||
await expect(payment_btn(page)).toBeVisible({ timeout: 8_000 });
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 3. Clicking CreditCard button opens the payment tab
|
||||
//
|
||||
// The button toggles active_tab to 'payment'. The payment component
|
||||
// (.ae-exhibit-payment or similar) must render inside the content area.
|
||||
// We verify by asserting the button switches to filled-success variant
|
||||
// (active tab styling) and the header primary button stays visible.
|
||||
// -----------------------------------------------------------------------
|
||||
test('clicking CreditCard button switches to payment tab', async ({ page }) => {
|
||||
await setup_leads_test_page(page, event_id, exhibit_id, {
|
||||
auth_kv: signed_in_kv,
|
||||
});
|
||||
|
||||
await page.goto(exhibit_url);
|
||||
|
||||
// Wait for the payment button to appear
|
||||
await expect(payment_btn(page)).toBeVisible({ timeout: 8_000 });
|
||||
|
||||
// Click it
|
||||
await payment_btn(page).click();
|
||||
|
||||
// Active tab styling: button gets preset-filled-success class
|
||||
await expect(payment_btn(page)).toHaveClass(/preset-filled-success/, {
|
||||
timeout: 3_000,
|
||||
});
|
||||
|
||||
// Primary "Add Lead / Lead List" toggle must still be visible
|
||||
await expect(
|
||||
page.locator('header button.preset-filled-primary')
|
||||
).toBeVisible({ timeout: 3_000 });
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 4. Manage tab: Billing accordion present when payment required
|
||||
//
|
||||
// When leads_require_payment is true, the Manage tab shows a collapsible
|
||||
// "Licenses & Billing" section so exhibitors can manage payment status.
|
||||
// -----------------------------------------------------------------------
|
||||
test('manage tab: billing accordion visible when payment required', async ({ page }) => {
|
||||
await setup_leads_test_page(page, event_id, exhibit_id, {
|
||||
auth_kv: signed_in_kv,
|
||||
});
|
||||
|
||||
await page.goto(exhibit_url);
|
||||
|
||||
// Wait for payment button (confirms event loaded and lq__event_obj is live)
|
||||
await expect(payment_btn(page)).toBeVisible({ timeout: 8_000 });
|
||||
|
||||
// Navigate to manage tab
|
||||
await manage_btn(page).click();
|
||||
|
||||
// Billing accordion row must be present
|
||||
await expect(
|
||||
page.locator('button:has-text("Licenses & Billing")')
|
||||
).toBeVisible({ timeout: 5_000 });
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 5. Manage tab: Billing accordion absent when payment not required
|
||||
//
|
||||
// When the flag is disabled the accordion is not rendered at all — the
|
||||
// conditional {#if leads_require_payment} in ae_tab__manage.svelte hides it.
|
||||
// -----------------------------------------------------------------------
|
||||
test('manage tab: billing accordion hidden when payment not required', async ({ page }) => {
|
||||
await setup_leads_test_page(page, event_id, exhibit_id, {
|
||||
auth_kv: signed_in_kv,
|
||||
event_data_overrides: {
|
||||
mod_exhibits_json: { leads_require_payment: false },
|
||||
},
|
||||
});
|
||||
|
||||
await page.goto(exhibit_url);
|
||||
|
||||
// Wait for event GET to complete
|
||||
await page.waitForResponse(
|
||||
(r) => r.url().includes(`crud/event/${event_id}`) && r.status() === 200,
|
||||
{ timeout: 8_000 }
|
||||
);
|
||||
|
||||
// Navigate to manage tab
|
||||
await manage_btn(page).click();
|
||||
|
||||
// "Booth Profile" section heading confirms manage tab is rendered
|
||||
await expect(page.locator('text=Booth Profile')).toBeVisible({ timeout: 5_000 });
|
||||
|
||||
// Billing accordion must NOT appear
|
||||
await expect(
|
||||
page.locator('button:has-text("Licenses & Billing")')
|
||||
).not.toBeVisible({ timeout: 3_000 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user