Files
app/tests/magnitude/node-publishing.mag.ts
Albert f0284ef813 feat: Improve UI layout and navigation
- Increase logo size (48x48 desktop, 56x56 mobile) for better visibility
- Add logo as favicon
- Add logo to mobile header
- Move user menu to navigation bars (sidebar on desktop, bottom bar on mobile)
- Fix desktop chat layout - container structure prevents voice controls cutoff
- Fix mobile bottom bar - use icon-only ActionIcons instead of truncated text buttons
- Hide Create Node/New Conversation buttons on mobile to save header space
- Make fixed header and voice controls work properly with containers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 14:43:11 +00:00

221 lines
7.8 KiB
TypeScript

/**
* 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');
});