Files
cv-site/tests/mjs/77-intro-text-justification.test.mjs
T
juanatsap aeaa9f2d62 test: add intro-text justification CSS verification test
Tests text-align, text-align-last, hyphens, word-spacing,
overflow-wrap, and font-style properties for both EN and ES
2025-12-02 18:18:43 +00:00

282 lines
10 KiB
JavaScript

#!/usr/bin/env bun
/**
* INTRO TEXT JUSTIFICATION TEST
* ==============================
* Tests the intro-text paragraph styling including:
* - Full text justification (text-align: justify)
* - Last line justification (text-align-last: justify)
* - Hyphenation support (hyphens: auto)
* - Cross-browser compatibility
*/
import { chromium } from 'playwright';
const URL = "http://localhost:1999";
async function testIntroTextJustification() {
console.log('📝 INTRO TEXT JUSTIFICATION TEST\n');
console.log('='.repeat(70));
const browser = await chromium.launch({ headless: true });
const errors = [];
const testResults = [];
// ========================================================================
// TEST 1: Verify intro-text element exists
// ========================================================================
console.log("\n1️⃣ Checking intro-text element exists...");
const page = await browser.newPage({ viewport: { width: 1076, height: 756 } });
page.on('console', msg => {
if (msg.type() === 'error') {
errors.push(msg.text());
console.log(`❌ ERROR: ${msg.text()}`);
}
});
await page.goto(URL);
await page.waitForTimeout(1500);
const elementExists = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
return {
exists: introText !== null,
textLength: introText ? introText.textContent.length : 0
};
});
if (elementExists.exists) {
console.log(` ✅ .intro-text element found (${elementExists.textLength} chars)`);
testResults.push({ test: "intro-text exists", passed: true });
} else {
console.log(" ❌ .intro-text element NOT found");
testResults.push({ test: "intro-text exists", passed: false });
}
// ========================================================================
// TEST 2: Verify text-align: justify
// ========================================================================
console.log("\n2️⃣ Checking text-align: justify...");
const textAlignTest = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
if (!introText) return { passed: false, value: 'element not found' };
const computed = window.getComputedStyle(introText);
const textAlign = computed.textAlign;
return {
passed: textAlign === 'justify',
value: textAlign
};
});
if (textAlignTest.passed) {
console.log(` ✅ text-align: ${textAlignTest.value}`);
testResults.push({ test: "text-align justify", passed: true });
} else {
console.log(` ❌ text-align: ${textAlignTest.value} (expected: justify)`);
testResults.push({ test: "text-align justify", passed: false });
}
// ========================================================================
// TEST 3: Verify text-align-last: justify
// ========================================================================
console.log("\n3️⃣ Checking text-align-last: justify...");
const textAlignLastTest = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
if (!introText) return { passed: false, value: 'element not found' };
const computed = window.getComputedStyle(introText);
const textAlignLast = computed.textAlignLast;
return {
passed: textAlignLast === 'justify',
value: textAlignLast
};
});
if (textAlignLastTest.passed) {
console.log(` ✅ text-align-last: ${textAlignLastTest.value}`);
testResults.push({ test: "text-align-last justify", passed: true });
} else {
console.log(` ❌ text-align-last: ${textAlignLastTest.value} (expected: justify)`);
testResults.push({ test: "text-align-last justify", passed: false });
}
// ========================================================================
// TEST 4: Verify hyphens: auto
// ========================================================================
console.log("\n4️⃣ Checking hyphens: auto...");
const hyphensTest = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
if (!introText) return { passed: false, value: 'element not found' };
const computed = window.getComputedStyle(introText);
// Note: Chromium returns 'auto' or 'manual' or 'none'
const hyphens = computed.hyphens || computed.webkitHyphens;
return {
passed: hyphens === 'auto',
value: hyphens
};
});
if (hyphensTest.passed) {
console.log(` ✅ hyphens: ${hyphensTest.value}`);
testResults.push({ test: "hyphens auto", passed: true });
} else {
console.log(` ❌ hyphens: ${hyphensTest.value} (expected: auto)`);
testResults.push({ test: "hyphens auto", passed: false });
}
// ========================================================================
// TEST 5: Verify word-spacing is set
// ========================================================================
console.log("\n5️⃣ Checking word-spacing...");
const wordSpacingTest = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
if (!introText) return { passed: false, value: 'element not found' };
const computed = window.getComputedStyle(introText);
const wordSpacing = computed.wordSpacing;
// We set word-spacing: -1px, but computed returns in px
const value = parseFloat(wordSpacing);
return {
passed: value < 0, // Should be negative
value: wordSpacing
};
});
if (wordSpacingTest.passed) {
console.log(` ✅ word-spacing: ${wordSpacingTest.value}`);
testResults.push({ test: "word-spacing negative", passed: true });
} else {
console.log(` ❌ word-spacing: ${wordSpacingTest.value} (expected: negative value)`);
testResults.push({ test: "word-spacing negative", passed: false });
}
// ========================================================================
// TEST 6: Verify overflow-wrap: break-word
// ========================================================================
console.log("\n6️⃣ Checking overflow-wrap: break-word...");
const overflowWrapTest = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
if (!introText) return { passed: false, value: 'element not found' };
const computed = window.getComputedStyle(introText);
const overflowWrap = computed.overflowWrap || computed.wordWrap;
return {
passed: overflowWrap === 'break-word',
value: overflowWrap
};
});
if (overflowWrapTest.passed) {
console.log(` ✅ overflow-wrap: ${overflowWrapTest.value}`);
testResults.push({ test: "overflow-wrap break-word", passed: true });
} else {
console.log(` ❌ overflow-wrap: ${overflowWrapTest.value} (expected: break-word)`);
testResults.push({ test: "overflow-wrap break-word", passed: false });
}
// ========================================================================
// TEST 7: Verify font-style: italic
// ========================================================================
console.log("\n7️⃣ Checking font-style: italic...");
const fontStyleTest = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
if (!introText) return { passed: false, value: 'element not found' };
const computed = window.getComputedStyle(introText);
const fontStyle = computed.fontStyle;
return {
passed: fontStyle === 'italic',
value: fontStyle
};
});
if (fontStyleTest.passed) {
console.log(` ✅ font-style: ${fontStyleTest.value}`);
testResults.push({ test: "font-style italic", passed: true });
} else {
console.log(` ❌ font-style: ${fontStyleTest.value} (expected: italic)`);
testResults.push({ test: "font-style italic", passed: false });
}
// ========================================================================
// TEST 8: Test on Spanish language (different hyphenation)
// ========================================================================
console.log("\n8️⃣ Testing Spanish version...");
await page.goto(`${URL}/?lang=es`);
await page.waitForTimeout(1500);
const spanishTest = await page.evaluate(() => {
const introText = document.querySelector('.intro-text');
const htmlLang = document.documentElement.lang;
if (!introText) return { passed: false, lang: htmlLang, hasText: false };
const computed = window.getComputedStyle(introText);
return {
passed: htmlLang === 'es' && computed.textAlign === 'justify',
lang: htmlLang,
hasText: introText.textContent.length > 0,
textAlign: computed.textAlign
};
});
if (spanishTest.passed) {
console.log(` ✅ Spanish version: lang="${spanishTest.lang}", text-align: ${spanishTest.textAlign}`);
testResults.push({ test: "spanish justification", passed: true });
} else {
console.log(` ❌ Spanish version failed - lang: ${spanishTest.lang}, text-align: ${spanishTest.textAlign}`);
testResults.push({ test: "spanish justification", passed: false });
}
// ========================================================================
// SUMMARY
// ========================================================================
console.log('\n' + '='.repeat(70));
console.log('📊 TEST SUMMARY\n');
const passed = testResults.filter(t => t.passed).length;
const total = testResults.length;
const consoleErrors = errors.filter(e => !e.includes('favicon'));
console.log(`Tests: ${passed}/${total} passed`);
console.log(`Console errors: ${consoleErrors.length}`);
if (consoleErrors.length > 0) {
console.log('\nConsole errors:');
consoleErrors.forEach(e => console.log(` - ${e}`));
}
console.log('\nDetailed results:');
testResults.forEach(t => {
console.log(` ${t.passed ? '✅' : '❌'} ${t.test}`);
});
await browser.close();
const success = passed === total && consoleErrors.length === 0;
console.log(`\n${success ? '✅ ALL TESTS PASSED' : '❌ SOME TESTS FAILED'}\n`);
process.exit(success ? 0 : 1);
}
testIntroTextJustification().catch(err => {
console.error('Test failed:', err);
process.exit(1);
});