Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions frontend/e2e/tool-style-consistency.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { test, expect } from '@playwright/test';

const TOOLS = [
'code-encoder',
'code-encrypter',
'hash-generator',
'code-converter',
'text-utilities',
'number-converter',
'datetime-converter',
'jwt',
'barcode',
'data-generator',
'code-formatter',
'color-converter',
'url-inspector',
'cron',
'regexp',
'diff',
];

const THEMES = [
{ mode: 'light', name: 'github-light' },
{ mode: 'dark', name: 'github-dark' },
];

async function setTheme(page, theme) {
await page.evaluate(({ mode, name }) => {
localStorage.setItem('dt-mode', mode);
localStorage.setItem('dt-name', name);
}, theme);
}

test.describe('Tool visual style consistency', () => {
for (const theme of THEMES) {
for (const slug of TOOLS) {
test(`${slug} keeps tool text and borders consistent in ${theme.mode}`, async ({ page }) => {
await page.goto(`/tool/${slug}`);
await setTheme(page, theme);
await page.goto(`/tool/${slug}`);
await page.waitForLoadState('networkidle');

const issues = await page.evaluate(() => {
const isVisible = (element, style) => {
const rect = element.getBoundingClientRect();
return (
rect.width > 0 &&
rect.height > 0 &&
style.visibility !== 'hidden' &&
style.display !== 'none' &&
style.opacity !== '0'
);
};

const selector = 'main, [data-testid="tool-page"], [role="main"]';
const root = document.querySelector(selector) ?? document.body;

return Array.from(root.querySelectorAll('*')).flatMap((element) => {
const style = getComputedStyle(element);
if (!isVisible(element, style)) return [];

const rect = element.getBoundingClientRect();
const text = element.textContent?.replace(/\s+/g, ' ').trim() ?? '';
const tag = element.tagName.toLowerCase();
const classes = element.className?.toString?.() ?? '';
const elementIssues = [];

const fontSize = parseFloat(style.fontSize);
const hasOwnText =
text.length > 0 &&
Array.from(element.children).every((child) => child.textContent?.trim() !== text);

if (hasOwnText && fontSize > 0 && fontSize < 11) {
elementIssues.push({
kind: 'font-size',
tag,
classes,
text: text.slice(0, 80),
value: style.fontSize,
});
}

const borderWidths = [
style.borderTopWidth,
style.borderRightWidth,
style.borderBottomWidth,
style.borderLeftWidth,
].map(parseFloat);

if (rect.width > 8 && rect.height > 8 && borderWidths.some((width) => width > 2)) {
elementIssues.push({
kind: 'border-width',
tag,
classes,
text: text.slice(0, 80),
value: borderWidths.join('/'),
});
}

return elementIssues;
});
});

expect(issues).toEqual([]);
});
}
}
});
2 changes: 1 addition & 1 deletion frontend/src/components/inputs/ToolCopyButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function ToolCopyButton({
size={size}
onClick={handleCopy}
disabled={isDisabled}
className={cn('h-7 gap-1.5 text-[10px] font-bold uppercase tracking-wider', className)}
className={cn('h-7 gap-1.5 text-[11px] font-bold uppercase tracking-wider', className)}
>
{copied ? <Check className="h-3 w-3" /> : <Copy className="h-3 w-3" />}
{copied ? 'Copied' : 'Copy'}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/inputs/ToolInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function ToolInput({
return (
<div className={cn('grid w-full items-center gap-1.5', containerClassName)}>
{label && (
<Label className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground/70 ml-1">
<Label className="text-[11px] font-bold uppercase tracking-wider text-muted-foreground/70 ml-1">
{label}
</Label>
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/inputs/ToolInputGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function ToolInputGroup({ label, children, className }) {
return (
<div className={cn('space-y-2', className)}>
{label && (
<h4 className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground/50 px-1">
<h4 className="text-[11px] font-bold uppercase tracking-widest text-muted-foreground/50 px-1">
{label}
</h4>
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/BarcodeGenerator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ export default function BarcodeGenerator() {
backgroundColor: 'var(--background)',
padding: '24px',
borderRadius: '12px',
border: '4px solid rgba(59, 130, 246, 0.2)',
border: '1px solid var(--border)',
}}
>
{output ? (
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/CodeConverter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function ToolPane({
gap: '4px',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/CodeEncoder/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ function ToolPane({
gap: '4px',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/CodeEncrypter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function ToolPane({
gap: '4px',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/pages/ColorConverter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ const ColorSwatch = ({ color, onClick, size = 40, showHex = true }) => (
height: size,
backgroundColor: color,
borderRadius: '6px',
border: '2px solid var(--border)',
border: '1px solid var(--border)',
}}
/>
{showHex && <CopyableHex hex={color} showColorPreview={false} style={{ fontSize: '10px' }} />}
{showHex && <CopyableHex hex={color} showColorPreview={false} style={{ fontSize: '11px' }} />}
</div>
);

Expand Down Expand Up @@ -446,7 +446,7 @@ HSB: ${hsb.h}, ${hsb.s}%, ${hsb.b}%`;
style={{
textAlign: 'left',
padding: '6px 8px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand All @@ -460,7 +460,7 @@ HSB: ${hsb.h}, ${hsb.s}%, ${hsb.b}%`;
style={{
textAlign: 'left',
padding: '6px 8px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand All @@ -473,7 +473,7 @@ HSB: ${hsb.h}, ${hsb.s}%, ${hsb.b}%`;
style={{
textAlign: 'center',
padding: '6px 8px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand Down Expand Up @@ -933,7 +933,7 @@ HSB: ${hsb.h}, ${hsb.s}%, ${hsb.b}%`;
backgroundColor: 'var(--border)',
border: '1px solid var(--border)',
color: 'var(--muted-foreground)',
fontSize: '10px',
fontSize: '11px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
Expand Down
20 changes: 10 additions & 10 deletions frontend/src/pages/CronJobParser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ export default function CronJobParser() {
style={{
padding: '8px 12px',
textAlign: 'left',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand All @@ -440,7 +440,7 @@ export default function CronJobParser() {
style={{
padding: '8px 12px',
textAlign: 'left',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand All @@ -453,7 +453,7 @@ export default function CronJobParser() {
style={{
padding: '8px 12px',
textAlign: 'left',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand All @@ -466,7 +466,7 @@ export default function CronJobParser() {
style={{
padding: '8px 12px',
textAlign: 'left',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand Down Expand Up @@ -572,7 +572,7 @@ export default function CronJobParser() {
style={{
padding: '8px 12px',
textAlign: 'left',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand All @@ -584,7 +584,7 @@ export default function CronJobParser() {
style={{
padding: '8px 12px',
textAlign: 'left',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand All @@ -597,7 +597,7 @@ export default function CronJobParser() {
style={{
padding: '8px 12px',
textAlign: 'left',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--muted-foreground)',
textTransform: 'uppercase',
Expand Down Expand Up @@ -650,7 +650,7 @@ export default function CronJobParser() {
{prevExecutions[1] && (
<div
style={{
fontSize: '10px',
fontSize: '11px',
color: 'var(--muted-foreground)',
marginTop: '4px',
}}
Expand Down Expand Up @@ -715,7 +715,7 @@ export default function CronJobParser() {
<div style={{ fontSize: '11px', fontWeight: 500, color: 'var(--primary)' }}>
Current
</div>
<div style={{ fontSize: '10px', color: 'var(--success)', marginTop: '4px' }}>
<div style={{ fontSize: '11px', color: 'var(--success)', marginTop: '4px' }}>
Next in
</div>
</td>
Expand Down Expand Up @@ -777,7 +777,7 @@ export default function CronJobParser() {
{nextExecutions[1] && (
<div
style={{
fontSize: '10px',
fontSize: '11px',
color: 'var(--muted-foreground)',
marginTop: '4px',
}}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/DataGenerator/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ function GroupedSelectDropdown({ label, value, onChange, groups, width = '200px'
<div
style={{
padding: '6px 10px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
color: 'var(--border)',
textTransform: 'uppercase',
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/DateTimeConverter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ export default function DateTimeConverter() {
<div style={{ fontSize: '12px', fontWeight: 600, color: 'var(--foreground)' }}>
{info.city}
</div>
<div style={{ fontSize: '10px', color: 'var(--muted-foreground)' }}>{info.timezone}</div>
<div style={{ fontSize: '11px', color: 'var(--muted-foreground)' }}>{info.timezone}</div>
</div>

{/* Time */}
Expand All @@ -424,7 +424,7 @@ export default function DateTimeConverter() {
{/* Offset */}
<div
style={{
fontSize: '10px',
fontSize: '11px',
color: 'var(--muted-foreground)',
padding: '2px 6px',
backgroundColor: 'var(--card)',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default function MultiHashOutput({ value, error }) {
onClick={() => handleCopy(val, idx)}
style={{
padding: '4px 8px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/HashGenerator/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function ToolPane({
gap: '4px',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down Expand Up @@ -392,7 +392,7 @@ export default function HashGenerator() {
gap: '4px',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/pages/RegExpTester.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ function LiveHighlightedEditor({ text, setText, regex, flags, label, indicator,
alignItems: 'center',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down Expand Up @@ -697,7 +697,7 @@ function QuickReferencePanel() {
cursor: 'pointer',
}}
>
<span style={{ fontSize: '10px' }}>{cat.icon}</span>
<span style={{ fontSize: '11px' }}>{cat.icon}</span>
<span>{cat.label}</span>
</button>
))}
Expand Down Expand Up @@ -898,7 +898,7 @@ function ResultPane({ label, matches, error, indicator, indicatorColor }) {
alignItems: 'center',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '10px',
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em',
Expand Down
Loading
Loading