mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-11-01 19:32:33 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91b8927c56 |
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import test from 'node:test';
|
||||
import React from 'react';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { JSDOM } from 'jsdom';
|
||||
import { compile } from '@tailwindcss/node';
|
||||
import postcss from 'postcss';
|
||||
import HostDetailsPanel from './HostDetailsPanel';
|
||||
import { Card } from './ui/card';
|
||||
import { TooltipProvider } from './ui/tooltip';
|
||||
import { PluginPermissionPanel } from './settings/tabs/PluginPermissionPanel';
|
||||
import { I18nProvider } from '../application/i18n/I18nProvider';
|
||||
|
||||
test('real Host form cards, inputs and Save consume scoped security aliases without freezing an ordinary card', async () => {
|
||||
const markup = renderToStaticMarkup(<I18nProvider locale="en"><TooltipProvider>
|
||||
<HostDetailsPanel availableKeys={[]} identities={[]} groups={[]} terminalThemeId="default" terminalFontSize={14} onSave={() => assert.fail('test never saves a host')} onCancel={() => {}} />
|
||||
<PluginPermissionPanel pluginId="com.example.synthetic" onChanged={async () => {}} />
|
||||
<Card id="ordinary-card">Outside the security surface</Card>
|
||||
</TooltipProvider></I18nProvider>);
|
||||
const dom = new JSDOM(`<!doctype html><html data-plugin-theme-active><body>${markup}</body></html>`);
|
||||
try {
|
||||
const panel = dom.window.document.querySelector('[data-section="host-details-panel"]')!;
|
||||
assert.ok(panel, 'exercise the actual HostDetailsPanel and AsidePanel');
|
||||
assert.ok(panel.querySelector('.bg-card'), 'General/Address/Credentials use real Card components');
|
||||
assert.ok(panel.querySelector('input.bg-background'), 'exercise actual Input utilities');
|
||||
assert.ok(panel.querySelector('button.bg-primary'), 'exercise the actual Save button');
|
||||
const permissions = dom.window.document.querySelector('[data-host-security-surface]')!;
|
||||
assert.ok(permissions.querySelector('[role="status"]'), 'exercise the real grant-panel security root without loading or changing any grants');
|
||||
const source = await readFile(new URL('../index.css', import.meta.url), 'utf8');
|
||||
const compiler = await compile(source, {base: path.resolve('.'), onDependency() {}});
|
||||
const classes = [...new Set([...dom.window.document.querySelectorAll('[class]')].flatMap(el => [...el.classList]))];
|
||||
const css = compiler.build(classes);
|
||||
const parsed = postcss.parse(css);
|
||||
const rules: postcss.Rule[] = [];
|
||||
parsed.walkRules(rule => { rules.push(rule); });
|
||||
const rule = rules.find(node => node.selector.startsWith(':root[data-plugin-theme-active]'));
|
||||
assert.ok(rule && rule.type === 'rule');
|
||||
const matches = [...dom.window.document.querySelectorAll(rule.selector)];
|
||||
assert.ok(matches.includes(panel));
|
||||
assert.ok(matches.includes(permissions));
|
||||
assert.ok(!matches.includes(dom.window.document.getElementById('ordinary-card')!), 'security selector stays within the existing marked surfaces');
|
||||
const declarations = new Map(rule.nodes.filter(node => node.type === 'decl').map(node => [node.prop, node]));
|
||||
for (const name of ['background','foreground','card','card-foreground','popover','popover-foreground','primary','primary-foreground','secondary','secondary-foreground','muted','muted-foreground','accent','accent-foreground','destructive','destructive-foreground','border','input','ring']) {
|
||||
const declaration = declarations.get(`--color-${name}`);
|
||||
assert.equal(declaration?.value, `hsl(var(--host-security-${name}))`, `Tailwind alias ${name} cannot inherit the plugin value`);
|
||||
assert.equal(declaration.important, true);
|
||||
}
|
||||
for (const name of ['card','background','primary']) {
|
||||
const utility = rules.find(node => node.selector === `.bg-${name}`);
|
||||
assert.ok(utility && utility.type === 'rule');
|
||||
assert.ok(utility.nodes.some(node => node.type === 'decl' && node.prop === 'background-color' && node.value === `var(--color-${name})`), 'verify what the actual compiled utility consumes');
|
||||
}
|
||||
const mutedText = rules.find(node => node.selector === '.text-muted-foreground');
|
||||
assert.ok(mutedText?.nodes.some(node => node.type === 'decl' && node.prop === 'color' && node.value === 'var(--color-muted-foreground)'));
|
||||
} finally { dom.window.close(); }
|
||||
});
|
||||
@@ -133,3 +133,27 @@ This is source identity and a source-based ordering diagnosis, not a claim that
|
||||
baseline runtime failure was reproduced locally. The updated test needs the new
|
||||
exact-head CI result. That same first run passed the added Vite browser-import
|
||||
smoke, resolving the earlier local temp-directory limitation for that head.
|
||||
|
||||
### Native security-color delta
|
||||
|
||||
Parent native acceptance at f868 verified zero-permission installation/enabling,
|
||||
light/dark Preview and Cancel, Apply across main/Settings windows, Restore
|
||||
default, restart persistence, and Disable fallback with the unavailable notice.
|
||||
The isolated schema-3 profile was not touched. These core results remain valid.
|
||||
|
||||
Native QA also found Forest-colored inner New Host cards/inputs/Save and some
|
||||
grant-panel text inside an otherwise fixed security container. The cause was
|
||||
Tailwind's derived `--color-*` aliases: changing only raw semantic tokens at the
|
||||
boundary does not recompute aliases already resolved on an ancestor. The same
|
||||
existing security rule now fixes both raw tokens and those color aliases. The
|
||||
selector and protected regions are unchanged; ordinary application cards remain
|
||||
theme-controlled. No host, credential or grant operation changed.
|
||||
|
||||
The regression renders the actual HostDetailsPanel (including General, Address,
|
||||
Credentials cards, real Inputs and Save), plus the real grant-panel root. It
|
||||
compiles the production Tailwind source, verifies which aliases those utilities
|
||||
consume, checks the fixed declarations, and verifies an ordinary card is outside
|
||||
the security selector. This is component/compiled-CSS coverage, not a claim of
|
||||
native computed-color acceptance. The parent's native color delta remains the
|
||||
final visual check. A local Chromium probe aborted because its SUID sandbox was
|
||||
not configured; sandboxing was not disabled to retry.
|
||||
@@ -2221,6 +2221,26 @@ html[data-theme-transition] *::after {
|
||||
--border: var(--host-security-border) !important;
|
||||
--input: var(--host-security-input) !important;
|
||||
--ring: var(--host-security-ring) !important;
|
||||
/* Tailwind theme aliases resolve where declared; pin them in this scope too. */
|
||||
--color-background: hsl(var(--host-security-background)) !important;
|
||||
--color-foreground: hsl(var(--host-security-foreground)) !important;
|
||||
--color-card: hsl(var(--host-security-card)) !important;
|
||||
--color-card-foreground: hsl(var(--host-security-card-foreground)) !important;
|
||||
--color-popover: hsl(var(--host-security-popover)) !important;
|
||||
--color-popover-foreground: hsl(var(--host-security-popover-foreground)) !important;
|
||||
--color-primary: hsl(var(--host-security-primary)) !important;
|
||||
--color-primary-foreground: hsl(var(--host-security-primary-foreground)) !important;
|
||||
--color-secondary: hsl(var(--host-security-secondary)) !important;
|
||||
--color-secondary-foreground: hsl(var(--host-security-secondary-foreground)) !important;
|
||||
--color-muted: hsl(var(--host-security-muted)) !important;
|
||||
--color-muted-foreground: hsl(var(--host-security-muted-foreground)) !important;
|
||||
--color-accent: hsl(var(--host-security-accent)) !important;
|
||||
--color-accent-foreground: hsl(var(--host-security-accent-foreground)) !important;
|
||||
--color-destructive: hsl(var(--host-security-destructive)) !important;
|
||||
--color-destructive-foreground: hsl(var(--host-security-destructive-foreground)) !important;
|
||||
--color-border: hsl(var(--host-security-border)) !important;
|
||||
--color-input: hsl(var(--host-security-input)) !important;
|
||||
--color-ring: hsl(var(--host-security-ring)) !important;
|
||||
color: hsl(var(--foreground)) !important;
|
||||
background-color: hsl(var(--background)) !important;
|
||||
border-color: hsl(var(--border)) !important;
|
||||
|
||||
Reference in new issue
Block a user