Added Vividus + AI promo page - #298
Conversation
📝 WalkthroughWalkthroughAdded a responsive VIVIDUS landing page with product sections, AI test-agent workflows, coverage details, assistant integrations, FAQ content, accessibility metadata, inline SVG assets, and interactive transcript playback. ChangesLanding page experience
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Visitor
participant IntersectionObserver
participant ChatPlayback
Visitor->>IntersectionObserver: Scrolls to chat section
IntersectionObserver->>ChatPlayback: Triggers initial playback
ChatPlayback->>Visitor: Shows staged messages and code lines
Visitor->>ChatPlayback: Activates replay
ChatPlayback->>Visitor: Replays the transcript
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/index.html`:
- Around line 212-216: Update the “Contact us” anchor in the navigation links to
use the existing `#_contact_us` fragment instead of `#_contract_us`, leaving the
surrounding links unchanged.
- Around line 334-335: Update the tab buttons with IDs t-api and t-mob to
explicitly set type="button", matching the existing replay button markup and
preventing them from defaulting to submit.
- Around line 8-13: Update the Open Graph metadata near the existing og:image
tag to use the page’s absolute publication URL for the image, and add an og:url
tag containing the page’s absolute URL. Preserve the existing image and page
metadata values otherwise.
- Around line 74-83: Update the mobile navigation around the .nav-links rule so
Documentation and Contact remain reachable below 700px; the preferred minimal
fix is to add both links to the footer alongside the existing GitHub link,
preserving the current CTA-focused mobile navigation behavior.
- Around line 333-344: Update the ARIA tab markup so the selected API tab has
tabindex="0", the unselected Mobile app tab has tabindex="-1", and both panels
(p-api and p-mob) have tabindex="0"; then update select() to move tabindex="0"
to the selected tab and set the other tab to "-1" whenever selection changes.
- Around line 495-504: Update the caret cleanup timer in the transcript typing
logic to run after the final line step is displayed, rather than using the fixed
at - 400 delay. Anchor cleanup to the last scheduled step so snippets ending the
transcript also remove the caret, while preserving the existing caret removal
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a81d9b26-3c1b-4abc-83f8-3bb7e1ec95b0
⛔ Files ignored due to path filters (1)
docs/vividus-logo.pngis excluded by!**/*.png
📒 Files selected for processing (2)
docs/.nojekylldocs/index.html
| <meta property="og:title" content="VIVIDUS — AI-assisted test automation"> | ||
| <meta property="og:description" content="Open-source test automation for web, mobile, APIs and more. Write tests in plain readable steps, or let Claude, Copilot or Cursor write them for you."> | ||
| <meta property="og:type" content="website"> | ||
| <meta property="og:image" content="vividus-logo.png"> | ||
| <meta name="theme-color" content="#0b0b0d"> | ||
| <link rel="icon" href="vividus-logo.png"> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Use an absolute URL for og:image.
Most Open Graph consumers do not resolve relative image paths. The preview image will not render when the page is shared. Add an absolute URL, and add og:url for completeness.
🔧 Proposed fix
<meta property="og:type" content="website">
-<meta property="og:image" content="vividus-logo.png">
+<meta property="og:url" content="https://vividus.dev/">
+<meta property="og:image" content="https://vividus.dev/vividus-logo.png">Replace the host with the actual publication origin of this page.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <meta property="og:title" content="VIVIDUS — AI-assisted test automation"> | |
| <meta property="og:description" content="Open-source test automation for web, mobile, APIs and more. Write tests in plain readable steps, or let Claude, Copilot or Cursor write them for you."> | |
| <meta property="og:type" content="website"> | |
| <meta property="og:image" content="vividus-logo.png"> | |
| <meta name="theme-color" content="#0b0b0d"> | |
| <link rel="icon" href="vividus-logo.png"> | |
| <meta property="og:title" content="VIVIDUS — AI-assisted test automation"> | |
| <meta property="og:description" content="Open-source test automation for web, mobile, APIs and more. Write tests in plain readable steps, or let Claude, Copilot or Cursor write them for you."> | |
| <meta property="og:type" content="website"> | |
| <meta property="og:url" content="https://vividus.dev/"> | |
| <meta property="og:image" content="https://vividus.dev/vividus-logo.png"> | |
| <meta name="theme-color" content="`#0b0b0d`"> | |
| <link rel="icon" href="vividus-logo.png"> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/index.html` around lines 8 - 13, Update the Open Graph metadata near the
existing og:image tag to use the page’s absolute publication URL for the image,
and add an og:url tag containing the page’s absolute URL. Preserve the existing
image and page metadata values otherwise.
| @media(max-width:820px){.nav-links{gap:18px}} | ||
| /* below this the three links crowd the CTA — the CTA is what matters, keep it alone */ | ||
| @media(max-width:700px){.nav-links a:not(.nav-cta){display:none}} | ||
| /* narrow phones: tighten the bar so the logo and CTA still fit side by side */ | ||
| @media(max-width:420px){ | ||
| .wrap{padding:0 16px} | ||
| nav{gap:12px} | ||
| .nav-cta{padding:10px 14px;font-size:.86rem} | ||
| .xs-hide{display:none} | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Mobile users lose the Documentation and Contact links.
Below 700px the rule at Line 76 hides every nav link except the CTA. The footer contains only the GitHub link, so Documentation and "Contact us" become unreachable on phones. Add these links to the footer, or add a compact menu.
🔧 Minimal fix in the footer
<p class="foot-note">Documentation, samples and source live on
<a href="https://github.com/vividus-framework/vividus">GitHub</a>.</p>
+ <p class="foot-note">
+ <a href="https://docs.vividus.dev/vividus/latest/index.html">Documentation</a> ·
+ <a href="https://docs.vividus.dev/vividus/latest/index.html#_contract_us">Contact us</a>
+ </p>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/index.html` around lines 74 - 83, Update the mobile navigation around
the .nav-links rule so Documentation and Contact remain reachable below 700px;
the preferred minimal fix is to add both links to the footer alongside the
existing GitHub link, preserving the current CTA-focused mobile navigation
behavior.
| <a href="https://docs.vividus.dev/vividus/latest/index.html">Documentation</a> | ||
| <a href="https://github.com/vividus-framework/vividus">GitHub</a> | ||
| <a href="https://docs.vividus.dev/vividus/latest/index.html#_contract_us">Contact us</a> | ||
| <!-- one span = one flex item, so the label words keep normal spacing, not the btn gap --> | ||
| <a class="btn btn-primary nav-cta" href="https://github.com/vividus-framework/vividus-starter/generate"><span>Create <span class="xs-hide">your </span>project</span></a> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Fetch the docs page and report which contact anchor exists.
url="https://docs.vividus.dev/vividus/latest/index.html"
body=$(curl -sL --max-time 30 "$url")
for id in _contract_us _contact_us; do
if printf '%s' "$body" | grep -qE "id=\"$id\""; then
echo "FOUND: $id"
else
echo "MISSING: $id"
fi
done
# Show any anchor that mentions contact
printf '%s' "$body" | grep -oE 'id="[^"]*cont[a-z_]*"' | sort -uRepository: vividus-framework/vividus-sample-tests
Length of output: 234
Fix the Contact us link fragment.
#_contract_us does not exist on the docs page; replace it with #_contact_us so the link reaches the contact section instead of the top of the page.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/index.html` around lines 212 - 216, Update the “Contact us” anchor in
the navigation links to use the existing `#_contact_us` fragment instead of
`#_contract_us`, leaving the surrounding links unchanged.
| <div class="tabs" role="tablist" aria-label="Example tests"> | ||
| <button class="tab" role="tab" id="t-api" aria-controls="p-api" aria-selected="true">API</button> | ||
| <button class="tab" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false">Mobile app</button> | ||
| </div> | ||
|
|
||
| <div role="tabpanel" id="p-api" aria-labelledby="t-api"> | ||
| <pre><span class="ln"><span class="k">Scenario</span>: Verify Luke's eyes are blue</span><span class="ln"><span class="k">When</span> I execute HTTP GET request for resource with URL <span class="s">`https://swapi.info/api/people/1/`</span></span><span class="ln"><span class="k">Then</span> <span class="v">`${responseCode}`</span> is equal to <span class="s">`200`</span></span><span class="ln"><span class="k">Then</span> JSON element value from <span class="v">`${response}`</span> by JSON path <span class="s">`$.eye_color`</span> is equal to <span class="s">`blue`</span></span></pre> | ||
| </div> | ||
|
|
||
| <div role="tabpanel" id="p-mob" aria-labelledby="t-mob" hidden> | ||
| <pre><span class="ln"><span class="k">Scenario</span>: User should be able to log in</span><span class="ln"><span class="k">When</span> I type <span class="s">`bob@example.com`</span> in field located <span class="s">`accessibilityId(Username input field)`</span></span><span class="ln"><span class="k">When</span> I type <span class="s">`10203040`</span> in field located <span class="s">`accessibilityId(Password input field)`</span></span><span class="ln"><span class="k">When</span> I tap on element located by <span class="s">`accessibilityId(Login button)`</span></span></pre> | ||
| </div> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Complete the ARIA tabs pattern with roving tabindex and focusable panels.
The current markup keeps every tab in the Tab sequence. The APG pattern puts only the selected tab in the sequence, and moves focus with the arrow keys. The panels also contain no focusable element, so keyboard users cannot reach the code content.
Set tabindex="-1" on unselected tabs and tabindex="0" on the panels, then update tabindex inside select().
♻️ Proposed change
- <button class="tab" type="button" role="tab" id="t-api" aria-controls="p-api" aria-selected="true">API</button>
- <button class="tab" type="button" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false">Mobile app</button>
+ <button class="tab" type="button" role="tab" id="t-api" aria-controls="p-api" aria-selected="true" tabindex="0">API</button>
+ <button class="tab" type="button" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false" tabindex="-1">Mobile app</button>
</div>
- <div role="tabpanel" id="p-api" aria-labelledby="t-api">
+ <div role="tabpanel" id="p-api" aria-labelledby="t-api" tabindex="0">Apply the same tabindex="0" to the panel at Line 342, and in select():
var selected = t === tab;
t.setAttribute('aria-selected', String(selected));
+ t.tabIndex = selected ? 0 : -1;
document.getElementById(t.getAttribute('aria-controls')).hidden = !selected;🧰 Tools
🪛 HTMLHint (1.9.2)
[warning] 334-334: The type attribute must be present on elements.
(button-type-require)
[warning] 335-335: The type attribute must be present on
elements.(button-type-require)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/index.html` around lines 333 - 344, Update the ARIA tab markup so the
selected API tab has tabindex="0", the unselected Mobile app tab has
tabindex="-1", and both panels (p-api and p-mob) have tabindex="0"; then update
select() to move tabindex="0" to the selected tab and set the other tab to "-1"
whenever selection changes.
| <button class="tab" role="tab" id="t-api" aria-controls="p-api" aria-selected="true">API</button> | ||
| <button class="tab" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false">Mobile app</button> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add type="button" to the tab buttons.
HTMLHint reports both buttons. The default type is submit. The replay button at Line 285 already sets type="button". Keep the markup consistent.
🔧 Proposed fix
- <button class="tab" role="tab" id="t-api" aria-controls="p-api" aria-selected="true">API</button>
- <button class="tab" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false">Mobile app</button>
+ <button class="tab" type="button" role="tab" id="t-api" aria-controls="p-api" aria-selected="true">API</button>
+ <button class="tab" type="button" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false">Mobile app</button>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <button class="tab" role="tab" id="t-api" aria-controls="p-api" aria-selected="true">API</button> | |
| <button class="tab" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false">Mobile app</button> | |
| <button class="tab" type="button" role="tab" id="t-api" aria-controls="p-api" aria-selected="true">API</button> | |
| <button class="tab" type="button" role="tab" id="t-mob" aria-controls="p-mob" aria-selected="false">Mobile app</button> |
🧰 Tools
🪛 HTMLHint (1.9.2)
[warning] 334-334: The type attribute must be present on elements.
(button-type-require)
[warning] 335-335: The type attribute must be present on
elements.(button-type-require)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/index.html` around lines 334 - 335, Update the tab buttons with IDs
t-api and t-mob to explicitly set type="button", matching the existing replay
button markup and preventing them from defaulting to submit.
Source: Linters/SAST tools
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/index.html`:
- Around line 704-706: Update the transcript playback flow around the chat
initialization, lock/unlock handling, and Replay controls to add a visible Stop
control while playback is active. Stop must invalidate the current runId, clear
all playback timers, pause the video, reveal remaining stages, remove the locked
state, and leave the transcript readable at its current pace; preserve Replay
for starting playback again.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 67754b28-4d33-47fe-8e6e-f8fbcc2a380d
⛔ Files ignored due to path filters (3)
docs/test-execution.mp4is excluded by!**/*.mp4docs/test-report.pngis excluded by!**/*.pngdocs/vividus-logo.pngis excluded by!**/*.png
📒 Files selected for processing (2)
docs/.nojekylldocs/index.html
| (function () { | ||
| var chat = document.querySelector('.chat'); | ||
| if (!chat || !window.matchMedia || matchMedia('(prefers-reduced-motion: reduce)').matches) return; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Add a control that stops automatic transcript playback.
Line 747 locks the transcript. It remains locked until Line 818. Lines 824-825 expose only Replay. A visitor without a configured reduced-motion preference cannot stop the automatic scrolling or read the transcript at a chosen pace. Add a visible Stop control during playback. It must invalidate runId, clear timers, pause the video, reveal the remaining stages, and remove locked.
Also applies to: 745-750, 815-825
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/index.html` around lines 704 - 706, Update the transcript playback flow
around the chat initialization, lock/unlock handling, and Replay controls to add
a visible Stop control while playback is active. Stop must invalidate the
current runId, clear all playback timers, pause the video, reveal remaining
stages, remove the locked state, and leave the transcript readable at its
current pace; preserve Replay for starting playback again.
Summary by CodeRabbit