full-photosynthesis-test.js•16.5 kB
#!/usr/bin/env node
/**
* Full Photosynthesis Lesson Test
* Tests the complete lesson that originally failed with HTTP 500 errors
*/
import { createComposerFormatter } from '../src/tools/format-for-composer.js';
import { createCompositionAPISaver } from '../src/tools/save-composition-api.js';
import { chromium } from 'playwright';
// Complete photosynthesis lesson data (the original failing case)
const photosynthesisLessonData = {
metadata: {
topic: "Fotossíntese: A Fábrica de Energia da Vida",
subject: "Ciências",
gradeLevel: "8º ano",
duration: 50,
learningObjectives: [
"Compreender o processo da fotossíntese e sua importância para a vida",
"Identificar as estruturas celulares envolvidas na fotossíntese",
"Analisar os fatores que influenciam a eficiência fotossintética",
"Relacionar a fotossíntese com questões ambientais contemporâneas"
],
bnccAlignment: "EF08CI05, EF08CI06, EF08CI13"
},
widgets: [
{
type: "head-1",
content: {
category: "CIÊNCIAS - BIOLOGIA",
author_name: "Professor(a) Virtual",
author_office: "Especialista em Biologia Celular"
}
},
{
type: "text-1",
content: {
text: `<h2>Introdução à Fotossíntese</h2>
<p>A fotossíntese é um dos processos mais importantes da natureza, responsável por converter energia luminosa em energia química. Este processo fundamental não apenas sustenta a vida das plantas, mas também é essencial para toda a cadeia alimentar do nosso planeta.</p>
<p>Durante a fotossíntese, as plantas capturam a luz solar e, através de uma série de reações químicas complexas, produzem glicose e oxigênio a partir de dióxido de carbono e água. Este processo ocorre principalmente nas folhas, especificamente em organelas chamadas cloroplastos.</p>
<p>A importância da fotossíntese vai além da produção de alimento para as plantas. Ela é responsável pela produção de praticamente todo o oxigênio que respiramos e pela remoção de grandes quantidades de dióxido de carbono da atmosfera, ajudando a regular o clima do nosso planeta.</p>`
}
},
{
type: "image-1",
content: {
image: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800",
caption: "Folhas verdes captando luz solar para o processo de fotossíntese"
}
},
{
type: "text-1",
content: {
text: `<h2>Estruturas Envolvidas na Fotossíntese</h2>
<p>A fotossíntese ocorre em estruturas celulares altamente especializadas. Vamos conhecer as principais:</p>
<h3>Cloroplastos</h3>
<p>Os cloroplastos são organelas exclusivas das células vegetais, responsáveis por capturar a energia luminosa. Dentro dos cloroplastos, encontramos:</p>
<p><strong>Tilacoides:</strong> Estruturas membranosas onde ocorrem as reações que dependem da luz. Contêm a clorofila e outros pigmentos fotossintéticos.</p>
<p><strong>Estroma:</strong> Fluido que envolve os tilacoides, onde ocorrem as reações que não dependem diretamente da luz.</p>
<p><strong>Clorofila:</strong> Pigmento verde que absorve a energia luminosa. É responsável pela cor verde característica das plantas.</p>`
}
},
{
type: "list-1",
content: {
items: [
"Clorofila a: Pigmento primário, absorve luz vermelha e azul",
"Clorofila b: Pigmento acessório, complementa a absorção de luz",
"Carotenoides: Pigmentos amarelos e alaranjados, proteção contra excesso de luz",
"Tilacoides: Compartimentos membranosos organizados em pilhas (grana)",
"Estroma: Matriz fluida rica em enzimas para síntese de carboidratos"
],
list_type: "numbered"
}
},
{
type: "text-1",
content: {
text: `<h2>As Duas Fases da Fotossíntese</h2>
<p>A fotossíntese pode ser dividida em duas fases principais, cada uma com suas características específicas:</p>
<h3>Fase Clara (Reações Dependentes da Luz)</h3>
<p>Esta fase ocorre nos tilacoides e depende diretamente da presença de luz. Durante esta etapa:</p>
<ul>
<li>A clorofila absorve energia luminosa</li>
<li>Moléculas de água são quebradas (fotólise)</li>
<li>Oxigênio é liberado como subproduto</li>
<li>ATP e NADPH são produzidos para fornecer energia</li>
</ul>
<h3>Fase Escura (Ciclo de Calvin)</h3>
<p>Esta fase ocorre no estroma e não depende diretamente da luz, mas utiliza os produtos da fase clara:</p>
<ul>
<li>CO₂ é fixado e convertido em compostos orgânicos</li>
<li>ATP e NADPH são utilizados como fonte de energia</li>
<li>Glicose é produzida como produto final</li>
</ul>`
}
},
{
type: "hotspots-1",
content: {
background_image: "https://images.unsplash.com/photo-1530587191325-3db32d826c18?w=800",
markers: [
{
x: "25%",
y: "30%",
title: "Tilacoides",
content: "Estruturas membranosas onde ocorre a fase clara da fotossíntese"
},
{
x: "60%",
y: "45%",
title: "Estroma",
content: "Região onde ocorre o Ciclo de Calvin (fase escura)"
},
{
x: "40%",
y: "20%",
title: "Clorofila",
content: "Pigmento que absorve energia luminosa para iniciar o processo"
}
]
}
},
{
type: "text-1",
content: {
text: `<h2>Equação Geral da Fotossíntese</h2>
<p>A fotossíntese pode ser resumida pela seguinte equação química:</p>
<p><strong>6CO₂ + 6H₂O + energia luminosa → C₆H₁₂O₆ + 6O₂</strong></p>
<p>Esta equação nos mostra que:</p>
<ul>
<li><strong>Reagentes:</strong> 6 moléculas de dióxido de carbono + 6 moléculas de água + energia luminosa</li>
<li><strong>Produtos:</strong> 1 molécula de glicose + 6 moléculas de oxigênio</li>
</ul>
<p>É importante notar que a energia luminosa é convertida em energia química armazenada nas ligações da glicose, que posteriormente pode ser liberada através da respiração celular.</p>`
}
},
{
type: "quiz-1",
content: {
questions: [
{
question: "Qual é a principal função da clorofila na fotossíntese?",
options: ["Absorver energia luminosa", "Produzir oxigênio", "Quebrar moléculas de água", "Fixar dióxido de carbono"],
correct_option: 0
},
{
question: "Em qual estrutura celular ocorre a fotossíntese?",
options: ["Mitocôndrias", "Núcleo", "Cloroplastos", "Ribossomos"],
correct_option: 2
},
{
question: "Qual é o produto final da fase escura da fotossíntese?",
options: ["Oxigênio", "ATP", "Glicose", "NADPH"],
correct_option: 2
}
],
max_attempts: 2
}
},
{
type: "text-1",
content: {
text: `<h2>Fatores que Afetam a Fotossíntese</h2>
<p>Diversos fatores ambientais podem influenciar a eficiência do processo fotossintético:</p>
<h3>Intensidade Luminosa</h3>
<p>A quantidade de luz disponível é fundamental. Muita luz pode causar danos, enquanto pouca luz limita o processo.</p>
<h3>Concentração de CO₂</h3>
<p>O dióxido de carbono é um reagente essencial. Ambientes com maior concentração de CO₂ podem aumentar a taxa fotossintética.</p>
<h3>Temperatura</h3>
<p>Afeta a velocidade das reações enzimáticas. Temperaturas muito altas ou baixas podem prejudicar o processo.</p>
<h3>Disponibilidade de Água</h3>
<p>A água é um reagente essencial e sua escassez pode limitar severamente a fotossíntese.</p>
<p>Compreender esses fatores é crucial para agricultura e conservação ambiental, pois permite otimizar as condições para o crescimento das plantas.</p>`
}
},
{
type: "flashcards-1",
content: {
flashcards_items: [
{
question: "Cloroplasto",
answer: "Organela onde ocorre a fotossíntese, contém clorofila e outros pigmentos"
},
{
question: "Tilacoide",
answer: "Estrutura membranosa onde ocorrem as reações dependentes da luz"
},
{
question: "Estroma",
answer: "Fluido do cloroplasto onde ocorre o Ciclo de Calvin"
},
{
question: "Clorofila",
answer: "Pigmento verde que absorve energia luminosa"
},
{
question: "Fotólise",
answer: "Quebra de moléculas de água usando energia luminosa"
}
]
}
},
{
type: "text-1",
content: {
text: `<h2>Importância Ecológica e Ambiental</h2>
<p>A fotossíntese desempenha um papel fundamental na manutenção da vida na Terra:</p>
<h3>Produção de Oxigênio</h3>
<p>Praticamente todo o oxigênio presente na atmosfera é produto da fotossíntese realizada por plantas, algas e cianobactérias.</p>
<h3>Remoção de CO₂</h3>
<p>As plantas absorvem grandes quantidades de dióxido de carbono da atmosfera, ajudando a regular o efeito estufa.</p>
<h3>Base da Cadeia Alimentar</h3>
<p>A glicose produzida pela fotossíntese é a base energética de praticamente todos os ecossistemas terrestres.</p>
<p>Devido ao aquecimento global e às mudanças climáticas, a fotossíntese torna-se ainda mais relevante como processo natural de sequestro de carbono.</p>`
}
}
]
};
async function testFullPhotosynthesisLesson() {
console.error('🌱 Full Photosynthesis Lesson Test - Complete Validation\n');
// Step 1: Format the complete lesson
console.error('📋 Step 1: Formatting complete photosynthesis lesson');
const formatter = createComposerFormatter();
const formatResult = await formatter.formatForComposer(photosynthesisLessonData);
if (!formatResult.success) {
console.error('❌ Format failed:', formatResult.error);
return;
}
const composerJSON = formatResult.data.composerJSON;
console.error('✅ Formatting successful:', composerJSON.structure.length, 'widgets');
// Step 2: Pre-save validation
console.error('\n📋 Step 2: Pre-save validation');
const jsonSize = JSON.stringify(composerJSON).length;
console.error('✅ Composition size:', jsonSize, 'bytes');
console.error('✅ Widget count:', composerJSON.structure.length);
// Validate key structures
const headerWidget = composerJSON.structure.find(w => w.type === 'head-1');
const quizWidget = composerJSON.structure.find(w => w.type === 'quiz-1');
const flashcardsWidget = composerJSON.structure.find(w => w.type === 'flashcards-1');
const hotspotsWidget = composerJSON.structure.find(w => w.type === 'hotspots-1');
console.error('✅ Header widget HTML-wrapped:', headerWidget.category.startsWith('<p>'));
console.error('✅ Quiz widget uses choices:', !!quizWidget.questions[0].choices);
console.error('✅ Flashcards widget present:', !!flashcardsWidget);
console.error('✅ Hotspots widget present:', !!hotspotsWidget);
// Step 3: API save test
console.error('\n📋 Step 3: Testing API save with complete lesson');
let browser;
try {
// Launch browser
browser = await chromium.launch({
headless: false,
slowMo: 100
});
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 }
});
const page = await context.newPage();
// Set up console logging
page.on('console', msg => {
if (msg.text().includes('Response status:') || msg.text().includes('✅') || msg.text().includes('❌')) {
console.error(`[BROWSER] ${msg.text()}`);
}
});
console.error('🔐 Authenticating via JWT redirect...');
// Authenticate via JWT redirect
await page.goto('http://localhost:8080', {
waitUntil: 'networkidle',
timeout: 30000
});
await page.waitForURL('**/composer.euconquisto.com/**', {
timeout: 15000
});
await page.waitForLoadState('networkidle');
await page.waitForTimeout(2000);
console.error('✅ Authentication successful');
// Test API save
console.error('💾 Testing API save with complete lesson...');
const startTime = Date.now();
const apiSaver = createCompositionAPISaver();
const saveResult = await apiSaver.saveCompositionAPI(composerJSON, page);
const endTime = Date.now();
const processingTime = endTime - startTime;
if (saveResult.success) {
console.error('✅ COMPLETE LESSON SAVE SUCCESSFUL!');
console.error(' Composition UID:', saveResult.data.compositionUid);
console.error(' Processing time:', processingTime, 'ms');
console.error(' File size:', saveResult.data.uploadDetails.fileSize, 'bytes');
console.error(' Widgets saved:', composerJSON.structure.length);
if (saveResult.optimizationApplied) {
console.error(' Optimization applied:', saveResult.optimizationDetails.reductionPercent + '%');
console.error(' Size saved:', saveResult.optimizationDetails.sizeSavings, 'bytes');
} else {
console.error(' No optimization needed');
}
console.error('\n🎯 COMPLETE LESSON TEST RESULTS:');
console.error(' ✅ JSON structure fix works for complex lessons');
console.error(' ✅ HTTP 500 errors completely resolved');
console.error(' ✅ All widget types save successfully');
console.error(' ✅ Performance excellent:', processingTime < 10000 ? 'FAST' : 'SLOW');
console.error(' ✅ System ready for production use');
// Step 4: Test composition editor opening
console.error('\n📋 Step 4: Testing composition editor opening');
try {
const compositionUrl = `https://composer.euconquisto.com/app/composition/view/uid/${saveResult.data.compositionUid}`;
console.error('🎯 Opening composition in editor...');
await page.goto(compositionUrl, {
waitUntil: 'networkidle',
timeout: 15000
});
await page.waitForTimeout(3000);
// Check if composition loaded
const compositionLoaded = await page.evaluate(() => {
return document.querySelector('[data-widget-type]') !== null;
});
if (compositionLoaded) {
console.error('✅ Composition opens successfully in editor');
console.error(' Widgets rendered and accessible');
} else {
console.error('⚠️ Composition saved but may have rendering issues');
}
} catch (error) {
console.error('⚠️ Could not verify composition editor opening:', error.message);
}
} else {
console.error('❌ COMPLETE LESSON SAVE FAILED');
console.error(' Error:', saveResult.error);
console.error(' Processing time:', processingTime, 'ms');
// Analyze the failure
if (saveResult.error.details?.httpStatus === 500) {
console.error('\n🔍 ANALYSIS:');
console.error(' ❌ HTTP 500 still occurring with large payload');
console.error(' 🔧 May need payload optimization after all');
} else {
console.error('\n🔍 ANALYSIS:');
console.error(' ℹ️ Different error type - not JSON structure');
console.error(' 🔧 May need investigation of other factors');
}
}
} catch (error) {
console.error('❌ Test failed:', error.message);
console.error('\n🔍 ANALYSIS:');
console.error(' ❌ System error occurred');
console.error(' 🔧 Check authentication, network, or system setup');
} finally {
if (browser) {
await browser.close();
}
}
}
async function main() {
try {
await testFullPhotosynthesisLesson();
} catch (error) {
console.error('💥 Test execution failed:', error);
}
}
main().catch(console.error);