runner: bump RUNNER_V ?v=3 → ?v=4 so test-shield removal loads

The test-shield (#test-shield) was added in loader.js (always fresh
via plugin manager ?v=time()) but the removal lives in runner.js
hideProgress(). runner.js was still cached at ?v=3 in the browser,
so the shield stayed after the run. Bumping to ?v=4 in loader.js +
all 42 test files forces a fresh runner.js load.

chore: bump version to 0.9.15

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.6 committed 2026-04-12 11:04:23 +02:00
1 parent 88108ecc1b
commit 088c225202
45 files changed
+45 -45

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
<?php
define('APP_NAME', 'hyprcrd');
define('APP_VERSION', '0.9.14');
define('APP_VERSION', '0.9.15');
// Database path — writable directory, outside webroot
define('DB_PATH', __DIR__ . '/data/hyprcrd.db');
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect, csrf } from './runner.js?v=3';
import { describe, it, expect, csrf } from './runner.js?v=4';
describe('API: Edge Cases', () => {
it('create card with special characters in title', async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect, csrf } from './runner.js?v=3';
import { describe, it, expect, csrf } from './runner.js?v=4';
describe('API: Cards CRUD', () => {
it('GET /api/cards returns array', async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Board Rendering', () => {
it('renders card elements', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Bucket Context Menu', () => {
afterEach(async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
describe('Bucket Bar', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll } from './runner.js?v=4';
describe('Calendar: Day Click', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=4';
describe('Calendar', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, beforeEach, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, beforeEach, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=4';
// ── Helpers ──
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, rightClick, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, rightClick, sleep, closeAll, csrf } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
describe('Card: Tag Operations', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, rightClick, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, rightClick, sleep, closeAll, csrf } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
async function makeCard(title, body = '') {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, rightClick, sleep, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, rightClick, sleep, csrf } from './runner.js?v=4';
describe('Context Menu', () => {
afterEach(async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll } from './runner.js?v=4';
import { showDialog } from '../../js/modules/dialog.js';
describe('Datepicker: Rendering', () => {
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Detail: Done Toggle', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll } from './runner.js?v=4';
describe('Detail View', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, type, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, type, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Editor: Color Picker', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, type, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, type, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Editor: Empty Title Prevention', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=4';
// Helper: set selection range in textarea
function selectRange(textarea, start, end) {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Editor: Structure', () => {
it('has all elements', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect, csrf } from './runner.js?v=3';
import { describe, it, expect, csrf } from './runner.js?v=4';
describe('Export: JSON ZIP', () => {
it('export endpoint returns ZIP', async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
describe('Favorites Bucket', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=4';
import { state, parseTags, sortedCards } from '../../js/modules/state.js';
describe('Filtering: Tag AND Logic', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=4';
describe('Gallery', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, pressKey, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, pressKey, sleep, closeAll } from './runner.js?v=4';
describe('Help', () => {
afterEach(() => closeAll());
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, pressKey, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Image Fullscreen Viewer', () => {
afterEach(async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=4';
function enableLines() {
const gutter = $('#editor-gutter');
+1 -1
View File
@@ -39,7 +39,7 @@ document.addEventListener('keydown', e => {
// Must match the `?v=…` suffix used in test files' `from './runner.js?v=…'`
// imports — bump both in lock-step to invalidate the runner.js cache.
const RUNNER_V = '?v=3';
const RUNNER_V = '?v=4';
function ensureProgressBar() {
if (document.getElementById('test-progress')) return;
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect } from './runner.js?v=3';
import { describe, it, expect } from './runner.js?v=4';
import { renderMd } from '../../js/modules/markdown.js';
describe('Markdown: Blank Lines', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect } from './runner.js?v=3';
import { describe, it, expect } from './runner.js?v=4';
import { renderMd, formatTodoItems, stripMd } from '../../js/modules/markdown.js';
import { state } from '../../js/modules/state.js';
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, sleep, closeAll } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
describe('Multi-Select', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect, $ } from './runner.js?v=3';
import { describe, it, expect, $ } from './runner.js?v=4';
describe('Notification Banner', () => {
it('banner element exists', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, type, pressKey, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, type, pressKey, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Quick Capture: Open/Close', () => {
afterEach(async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect, csrf } from './runner.js?v=3';
import { describe, it, expect, csrf } from './runner.js?v=4';
describe('Relay: Push API', () => {
it('push without config returns error', async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect } from './runner.js?v=3';
import { describe, it, expect } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
// RRULE is set by CalDAV sync, not via PATCH. Test the data model and existing cards.
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, type, pressKey, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, type, pressKey, sleep, closeAll, csrf } from './runner.js?v=4';
describe('Search: Tag + Text Combined', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, type, pressKey, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, type, pressKey, sleep, closeAll } from './runner.js?v=4';
describe('Search', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, closeAll, sleep } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, closeAll, sleep } from './runner.js?v=4';
describe('Settings: Open/Close', () => {
afterEach(() => closeAll());
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect, $ } from './runner.js?v=3';
import { describe, it, expect, $ } from './runner.js?v=4';
describe('App Shell', () => {
it('header with logo', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=4';
// Helper: simulate typing a snippet trigger in the editor body
function typeSnippet(bodyEl, trigger) {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect, csrf } from './runner.js?v=3';
import { describe, it, expect, csrf } from './runner.js?v=4';
import { state, sortedCards } from '../../js/modules/state.js';
describe('Sorting: All Modes', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect } from './runner.js?v=3';
import { describe, it, expect } from './runner.js?v=4';
import { state, parseTags, sortedCards, getChildren, getGroupCards, getRecent, markRecent, getFavorites, toggleFavorite, isFavorite } from '../../js/modules/state.js';
describe('State: parseTags', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, sleep, closeAll, csrf } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
// Helper: create a bucket with the given name and return its row.
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, closeAll, sleep } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, closeAll, sleep } from './runner.js?v=4';
describe('Theme', () => {
it('CSS custom properties set', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, click, sleep, closeAll } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
describe('Toolbar: Filter Toggles', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, afterEach, expect, $, $$, click, type, rightClick, pressKey, sleep, closeAll, csrf } from './runner.js?v=3';
import { describe, it, afterEach, expect, $, $$, click, type, rightClick, pressKey, sleep, closeAll, csrf } from './runner.js?v=4';
import { state } from '../../js/modules/state.js';
function ctrlZ() {