// Spec: docs/specs/wave-based-slack-onboarding.md // Test plan: docs/specs/wave-based-slack-onboarding-tests.md §6 + §7 // // SCAFFOLD: every test is `.skip`ed and contains a TODO. As the UI lands, // unskip and fill in selectors / fixtures. // // These cover the rendered behavior that unit tests can't: dashboard line // visibility under different member statuses, and the admin-list "Mark as // Slack invited" button + status display. import { test, expect } from './helpers/fixtures.js' test.describe('Member dashboard — Slack-coming note (§7)', () => { test.skip('shows note for active member without Slack (7.1)', async () => { // TODO: seed a member { status: 'active', slackInvited: false }, sign in, // navigate to /member/dashboard, assert the one-liner is visible: // await expect(page.getByText(/within 2.3 weeks/i)).toBeVisible() }) test.skip('hides note once slackInvited:true (7.2)', async () => { // TODO: same as 7.1 but with slackInvited:true; assert text not present. }) test.skip('hides note for pending_payment member (7.3)', async () => { // TODO: pending_payment + slackInvited:false; assert text not present. }) test.skip('hides note for suspended/cancelled/guest (7.4)', async () => { // TODO: parameterize across statuses { suspended, cancelled, guest }. }) test.skip('copy contains no wave/cohort/batch language (7.5)', async ({ adminPage }) => { await adminPage.goto('/member/dashboard') const html = await adminPage.content() expect(html).not.toMatch(/\bwave\b/i) expect(html).not.toMatch(/\bcohort\b/i) expect(html).not.toMatch(/\bbatch\b/i) }) test.skip('renders as plain text — no banner / modal / callout styling (7.6)', async () => { // TODO: assert the note's container is not a UAlert / modal / heavy callout // (e.g. no .alert, no role="dialog" wrapper). }) test.skip('SSR renders without auth — note absent (7.7)', async ({ browser }) => { const context = await browser.newContext() const page = await context.newPage() const response = await page.goto('/member/dashboard') const ssrHtml = await response.text() expect(ssrHtml).not.toMatch(/within 2.3 weeks/i) await context.close() }) test.skip('copy matches approved wording (7.8)', async () => { // TODO: replace with the final approved string once the Open Question is resolved. }) }) test.describe('Admin members — Slack-invited control (§6)', () => { test.skip('shows "Mark as Slack invited" for slackInvited:false (6.1)', async ({ adminPage }) => { await adminPage.goto('/admin/members') // TODO: locate a row for a member with slackInvited:false and assert the // button is visible. // await expect(adminPage.getByRole('button', { name: /Mark as Slack invited/i })).toBeVisible() }) test.skip('replaces button with "Invited " once flipped (6.2)', async () => { // TODO: click the button on a row; assert button is gone, date string visible. }) test.skip('click triggers single PATCH and updates row in place (6.4)', async ({ adminPage }) => { // TODO: spy on network for /api/admin/members/*/slack-status; click button; // assert single PATCH, success, no full-page reload. }) test.skip('status labels read "Not yet invited" / "Invited" — not "Pending" (6.5)', async ({ adminPage }) => { await adminPage.goto('/admin/members') // TODO: // await expect(adminPage.getByText(/Not yet invited/i).first()).toBeVisible() // const html = await adminPage.content() // expect(html).not.toMatch(/Slack:\s*Pending/i) }) test.skip('member detail page mirrors list controls (6.6)', async () => { // TODO: navigate to /admin/members/; assert button + date display. }) test.skip('no UI references slackInviteStatus (6.7)', async ({ adminPage }) => { // Static assertion of rendered HTML — no leftover badge labels keyed off the dropped field. await adminPage.goto('/admin/members') const html = await adminPage.content() expect(html).not.toMatch(/slackInviteStatus/) }) test.skip('UI rolls back on PATCH error — no false "Invited" badge (6.8)', async () => { // TODO: mock the endpoint to return 500; assert the row stays in // "Not yet invited" state. }) test.skip('proposed: sortable on slackInvitedAt + filter "no Slack yet" (6.9)', async () => { // TODO: dependent on Open Question — wire up if implemented. }) })