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
41 changes: 20 additions & 21 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
<html lang="en">

<head>
<meta charset="UTF-8" >
<meta name="viewport" content="width=device-width, initial-scale=1.0" >
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QyverixAI — AI Developer Assistant</title>
<link rel="preconnect" href="https://fonts.googleapis.com" >
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="icon" type="image/svg+xml" href="../assets/icon.svg">
<link
href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=JetBrains+Mono:wght@400;500;600&family=Inter:wght@400;500;600&display=swap"
rel="stylesheet" >
rel="stylesheet">
<script>
(function() {
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
Expand Down Expand Up @@ -514,7 +514,7 @@
font-size: 15px;
}

.feat-pill-info h4 {
.feat-pill-info h2 {
font-size: 0.82rem;
font-weight: 600;
margin-bottom: 1px
Expand Down Expand Up @@ -2052,7 +2052,7 @@
<div class="badge-dot"></div>
<span data-i18n="hero_badge">Open Source · AI-Powered · Free</span>
</div>
<h1 data-i18n="hero_title">Debug. Understand.<br ><em>Ship faster.</em></h1>
<h1 data-i18n="hero_title">Debug. Understand.<br><em>Ship faster.</em></h1>
<p class="hero-sub" data-i18n="hero_subtitle">
Paste your code and get instant bug detection, plain-English explanations, and actionable improvement
suggestions — no account needed.
Expand Down Expand Up @@ -2156,7 +2156,7 @@ <h2 data-i18n="pill_upload_title">File Upload</h2>
</svg>
</button>
<input type="file" id="fileInput" accept=".py,.js,.ts,.java,.cpp,.cc,.cxx,.c,.h,.hpp,.kt,.kts,.txt,.zip" style="display:none"
tabindex="-1" >
tabindex="-1">
<button class="icon-btn" id="clearBtn" title="Clear" data-i18n-title="btn_clear" data-i18n-aria-label="btn_clear" aria-label="Clear code editor">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
aria-hidden="true">
Expand All @@ -2178,11 +2178,11 @@ <h2 data-i18n="pill_upload_title">File Upload</h2>

<!-- Language tabs -->
<div class="lang-tabs" role="group" aria-label="Select Programming Language">
<button class="lang-tab active" data-lang="python" data-i18n="lang_tab_python">Python</button>
<button class="lang-tab" data-lang="javascript" data-i18n="lang_tab_javascript">JavaScript</button>
<button class="lang-tab" data-lang="typescript" data-i18n="lang_tab_typescript">TypeScript</button>
<button class="lang-tab" data-lang="java" data-i18n="lang_tab_java">Java</button>
<button class="lang-tab" data-lang="cpp" data-i18n="lang_tab_cpp">C++</button>
<button class="lang-tab active" data-lang="python" aria-pressed="true" data-i18n="lang_tab_python">Python</button>
<button class="lang-tab" data-lang="javascript" aria-pressed="false" data-i18n="lang_tab_javascript">JavaScript</button>
<button class="lang-tab" data-lang="typescript" aria-pressed="false" data-i18n="lang_tab_typescript">TypeScript</button>
<button class="lang-tab" data-lang="java" aria-pressed="false" data-i18n="lang_tab_java">Java</button>
<button class="lang-tab" data-lang="cpp" aria-pressed="false" data-i18n="lang_tab_cpp">C++</button>
</div>
<!-- Editor area (line numbers + code editor) -->
<div class="editor-wrap">
Expand Down Expand Up @@ -2225,25 +2225,25 @@ <h2 data-i18n="pill_upload_title">File Upload</h2>
</div>

<div class="result-tabs" role="tablist" aria-label="Result Tabs" style="margin-bottom:12px">
<button id="tab-explain" class="result-tab active" data-rtab="explain" role="tab" aria-selected="true" aria-controls="pane-explain">
<button class="result-tab active" id="tab-explain" data-rtab="explain" role="tab" aria-selected="true" aria-controls="pane-explain">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/></svg>
<span data-i18n="tab_explain">Explain</span>
<span class="tab-badge" id="explainBadge"></span>
</button>
<button id="tab-debug" class="result-tab" data-rtab="debug" role="tab" aria-selected="false" aria-controls="pane-debug">
<button class="result-tab" id="tab-debug" data-rtab="debug" role="tab" aria-selected="false" aria-controls="pane-debug">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M8 2l1.5 1.5"/></svg>
<span data-i18n="tab_debug">Debug</span>
<span class="tab-badge" id="debugBadge"></span>
</button>
<button id="tab-suggest" class="result-tab" data-rtab="suggest" role="tab" aria-selected="false" aria-controls="pane-suggest">
<button class="result-tab" id="tab-suggest" data-rtab="suggest" role="tab" aria-selected="false" aria-controls="pane-suggest">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polygon points="13,2 3,14 12,14 11,22 21,10 12,10"/></svg>
<span data-i18n="tab_improve">Improve</span>
<span class="tab-badge" id="suggestBadge"></span>
</button>
</div>
<div class="result-content">
<!-- Explain Pane -->
<div class="result-pane active" id="pane-explain" role="tabpanel" tabindex="0" aria-label="Explanation Panel" aria-labelledby="tab-explain">
<div class="result-pane active" id="pane-explain" role="tabpanel" tabindex="0" aria-labelledby="tab-explain">
<div class="empty-state" id="emptyExplain">
<div class="empty-icon" aria-hidden="true"><svg width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="1.5">
Expand All @@ -2256,7 +2256,7 @@ <h3 data-i18n="empty_explain_title">No analysis yet</h3>
<div id="explainResult" style="display:none"></div>
</div>
<!-- Debug Pane -->
<div class="result-pane" id="pane-debug" role="tabpanel" tabindex="0" aria-label="Debugging Panel" aria-labelledby="tab-debug">
<div class="result-pane" id="pane-debug" role="tabpanel" tabindex="0" aria-labelledby="tab-debug">
<div class="empty-state" id="emptyDebug">
<div class="empty-icon" aria-hidden="true"><svg width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="1.5">
Expand All @@ -2276,7 +2276,7 @@ <h3 data-i18n="empty_debug_title">No bugs scanned</h3>
<div id="debugResult" style="display:none"></div>
</div>
<!-- Suggest Pane -->
<div class="result-pane" id="pane-suggest" role="tabpanel" tabindex="0" aria-label="Suggestions Panel" aria-labelledby="tab-suggest">
<div class="result-pane" id="pane-suggest" role="tabpanel" tabindex="0" aria-labelledby="tab-suggest">
<div class="empty-state" id="emptySuggest">
<div class="empty-icon" aria-hidden="true"><svg width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="1.5">
Expand Down Expand Up @@ -3140,7 +3140,7 @@ <h3 data-i18n="empty_suggest_title">No suggestions yet</h3>
document.querySelectorAll('.lang-tab').forEach(t => {
const isActive = t.dataset.lang === lang;
t.classList.toggle('active', isActive);
t.setAttribute('aria-selected', isActive ? 'true' : 'false');
t.setAttribute('aria-pressed', isActive ? 'true' : 'false');
});

// 2. Check if the editor currently contains one of the samples
Expand Down Expand Up @@ -4090,7 +4090,7 @@ <h3>${getTranslation('suggest_quality_score')}</h3>
SAMPLE CODE LOADER
═══════════════════════════════════════════════════════════════ */
const SAMPLES = {
python: `// Python Sample
python: `# Python Sample
import os

# [!] Hardcoded secret - security risk
Expand Down Expand Up @@ -4267,4 +4267,3 @@ <h3>${getTranslation('suggest_quality_score')}</h3>
</body>

</html>

28 changes: 27 additions & 1 deletion frontend/tests/e2e/analyze.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,30 @@ test('uploads a sample file and renders analysis results', async ({ page }) => {
await expect(summary).toHaveText(
'A short Python snippet (3 lines) that performs a focused task. Good starting point for learners.'
);
});
});

test('drag-and-drop upload auto-selects the detected language tab', async ({ page }) => {
await page.goto('/app/');

const editor = page.locator('#codeEditor').first();
const javaTab = page.locator('.lang-tab[data-lang="java"]').first();
const activeTab = page.locator('.lang-tab.active').first();

await javaTab.click();
await expect(activeTab).toHaveAttribute('data-lang', 'java');

const dataTransfer = await page.evaluateHandle(() => {
const transfer = new DataTransfer();
transfer.items.add(
new File(['const answer: number = 42;\n'], 'sample.ts', {
type: 'text/typescript',
})
);
return transfer;
});

await page.locator('body').dispatchEvent('drop', { dataTransfer });

await expect(editor).toHaveValue('const answer: number = 42;\n');
await expect(activeTab).toHaveAttribute('data-lang', 'typescript');
});
8 changes: 5 additions & 3 deletions frontend/tests/sample-comments.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const assert = require('assert');
const fs = require('fs');
const path = require('path');
import assert from 'node:assert';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const indexHtml = fs.readFileSync(path.resolve(__dirname, '..', 'index.html'), 'utf8');

const expectedHeaders = {
Expand Down
Loading