/** * Magnitude Tests: Node Publishing Flow * * Tests for the complete node creation, editing, and publishing workflow. * Covers both happy path and error scenarios. */ import { test } from 'magnitude-test'; // ============================================================================ // HAPPY PATH TESTS // ============================================================================ test('User can publish a node from conversation', async (agent) => { await agent.open('http://localhost:3000'); // Step 1: Login with Bluesky await agent.act('Click the "Log in with Bluesky" button'); await agent.check('Redirected to Bluesky login page'); await agent.act('Fill in username and password') .data({ username: process.env.TEST_BLUESKY_USERNAME || 'test-user.bsky.social', password: process.env.TEST_BLUESKY_PASSWORD || 'test-password', }); await agent.act('Click the login submit button'); await agent.check('Redirected back to app and logged in'); await agent.check('Chat interface is visible'); // Step 2: Start a conversation await agent.act('Type "Let\'s discuss the philosophy of decentralized social networks" into the chat input and press Enter'); await agent.check('Message appears in chat'); await agent.check('AI response appears'); // Step 3: Create node draft await agent.act('Click the "Create Node" button'); await agent.check('Navigated to edit page'); await agent.check('Title input has AI-generated content'); await agent.check('Content textarea has AI-generated content'); await agent.check('Conversation context is visible at the bottom'); // Step 4: Publish the node await agent.act('Click the "Publish Node" button'); await agent.check('Success notification appears with "Node published!"'); await agent.check('Returned to conversation view'); }); test('User can edit node draft before publishing', async (agent) => { // Assumes user is already logged in from previous test await agent.open('http://localhost:3000/chat'); // Start conversation await agent.act('Type "Testing the edit flow" and press Enter'); await agent.check('AI responds'); // Create draft await agent.act('Click "Create Node"'); await agent.check('On edit page with draft content'); // Edit the content await agent.act('Clear the title input and type "My Custom Title"'); await agent.act('Modify the content textarea to add "This is my edited content."'); await agent.check('Title shows "My Custom Title"'); await agent.check('Content includes "This is my edited content."'); // Publish await agent.act('Click "Publish Node"'); await agent.check('Success notification appears'); }); test('User can cancel node draft without publishing', async (agent) => { await agent.open('http://localhost:3000/chat'); // Start conversation await agent.act('Type "Test cancellation" and press Enter'); await agent.check('AI responds'); // Create draft await agent.act('Click "Create Node"'); await agent.check('On edit page'); // Cancel instead of publishing await agent.act('Click the "Cancel" button'); await agent.check('Returned to conversation view'); await agent.check('Draft was not published'); // Verify no success notification }); // ============================================================================ // UNHAPPY PATH TESTS // ============================================================================ test('Cannot publish node without authentication', async (agent) => { // Open edit page directly without being logged in await agent.open('http://localhost:3000/edit'); await agent.check('Shows empty state message'); await agent.check('Message says "No Node Draft"'); await agent.check('Suggests to start a conversation'); }); test('Cannot publish node with empty title', async (agent) => { await agent.open('http://localhost:3000/chat'); // Create draft await agent.act('Type "Test empty title validation" and press Enter'); await agent.check('AI responds'); await agent.act('Click "Create Node"'); await agent.check('On edit page'); // Clear the title await agent.act('Clear the title input completely'); await agent.check('Publish button is disabled'); }); test('Cannot publish node with empty content', async (agent) => { await agent.open('http://localhost:3000/chat'); // Create draft await agent.act('Type "Test empty content validation" and press Enter'); await agent.check('AI responds'); await agent.act('Click "Create Node"'); await agent.check('On edit page'); // Clear the content await agent.act('Clear the content textarea completely'); await agent.check('Publish button is disabled'); }); test('Shows error notification if publish fails', async (agent) => { await agent.open('http://localhost:3000/chat'); // Create draft await agent.act('Type "Test error handling" and press Enter'); await agent.check('AI responds'); await agent.act('Click "Create Node"'); await agent.check('On edit page'); // Simulate network failure by disconnecting (this is a mock scenario) // In real test, this would require mocking the API await agent.act('Click "Publish Node"'); // If there's a network error, should see error notification // Note: This test may need to mock the fetch call to force an error await agent.check('Either success or error notification appears'); }); test('Handles long content with truncation', async (agent) => { await agent.open('http://localhost:3000/chat'); // Create a very long message const longMessage = 'A'.repeat(500) + ' This is a test of long content truncation for Bluesky posts.'; await agent.act(`Type "${longMessage}" and press Enter`); await agent.check('AI responds'); await agent.act('Click "Create Node"'); await agent.check('On edit page'); await agent.act('Click "Publish Node"'); // Should still publish successfully (with truncation) await agent.check('Success notification appears'); await agent.check('May show warning about cache or truncation'); }); test('Shows warning when cache fails but publish succeeds', async (agent) => { await agent.open('http://localhost:3000/chat'); await agent.act('Type "Test cache failure graceful degradation" and press Enter'); await agent.check('AI responds'); await agent.act('Click "Create Node"'); await agent.check('On edit page'); await agent.act('Click "Publish Node"'); // The system should succeed even if cache/embeddings fail await agent.check('Success notification appears'); // May show yellow warning notification instead of green success await agent.check('Notification says "Node published"'); }); // ============================================================================ // INTEGRATION TESTS // ============================================================================ test('Complete user journey: Login → Converse → Publish → View', async (agent) => { // Full end-to-end test await agent.open('http://localhost:3000'); // Login await agent.act('Login with Bluesky') .data({ username: process.env.TEST_BLUESKY_USERNAME, password: process.env.TEST_BLUESKY_PASSWORD, }); await agent.check('Logged in successfully'); // Have a meaningful conversation await agent.act('Type "I want to explore the concept of digital gardens" and send'); await agent.check('AI responds with insights'); await agent.act('Reply with "How do digital gardens differ from blogs?"'); await agent.check('AI provides detailed explanation'); // Create and publish await agent.act('Click "Create Node"'); await agent.check('Draft generated from conversation'); await agent.act('Review the draft and click "Publish Node"'); await agent.check('Node published successfully'); // Verify we can continue the conversation await agent.check('Back in conversation view'); await agent.check('Can type new messages'); });