feat(quick-260921-qd3): XFrame-Widget - Webseite als Rahmen im Dashboard, Sandbox ohne Top-Navigation, Neuladen-Intervall
- xframe-config.ts: Resolver (https-Pruefung via isHttpsUrl des Bilderrahmens, Titel bis 100 Zeichen, Neuladen 0/60/300/600/1800/3600 s geklemmt), XFRAME_SANDBOX ohne allow-top-navigation und allow-modals; 12 Tests zuerst rot - xframe-widget.tsx: genau ein <iframe> (sandbox, allow="", no-referrer, lazy), Kopfleiste mit Titel oder Ecksymbol "In neuem Tab oeffnen", Neuladen ueber key-Wechsel mit Timer-Raeumung, transparente Flaeche im Bearbeitungsmodus damit die Kachel Ziehgriff bleibt; 12 Tests zuerst rot - xframe-config-form.tsx: Adresse/Titel mit Uebernahme bei Blur/Enter, http wird mit Meldung abgewiesen und nicht gespeichert, Intervall-Auswahl, dauerhafter Hinweis auf verweigertes Einbetten; 8 Tests - Panel-Zweig samt "— Titel" in der Kopfzeile, Registry (12x12, Fenster-Symbol), Katalog, Seite, DTO @IsIn, de/en widgets.xframe (15 Schluessel), Umlaut-Allowlist "neuem"; der Server ruft die Adresse nie ab Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -234,3 +234,32 @@ describe('WidgetSettingsPanel — Favoriten-Titel (quick-260916-iex)', () => {
|
||||
expect(screen.queryByText('Title')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
const xframe = (de as { widgets: { xframe: Record<string, string> } }).widgets.xframe;
|
||||
|
||||
describe('WidgetSettingsPanel — XFrame (quick-260921-qd3)', () => {
|
||||
it('Test X1: der Zweig rendert das XFrame-Formular, Kopfzeile zeigt "— Titel", Blur der Adresse ruft updateWidgetConfig/onWidgetUpdate', async () => {
|
||||
const onWidgetUpdate = vi.fn();
|
||||
const widget = {
|
||||
id: 'x1',
|
||||
widgetType: 'xframe',
|
||||
config: { url: 'https://intern.example/board', title: 'Board', reloadSeconds: 300 },
|
||||
};
|
||||
render(<WidgetSettingsPanel widgets={[widget]} onWidgetUpdate={onWidgetUpdate} />);
|
||||
const header = screen.getByRole('button', { name: /XFrame #1/ });
|
||||
expect(header).toHaveTextContent('— Board');
|
||||
fireEvent.click(header);
|
||||
|
||||
const url = screen.getByLabelText(xframe.urlLabel) as HTMLInputElement;
|
||||
expect(url.value).toBe('https://intern.example/board');
|
||||
expect((screen.getByLabelText(xframe.titleLabel) as HTMLInputElement).value).toBe('Board');
|
||||
expect((screen.getByLabelText(xframe.reloadLabel) as HTMLSelectElement).value).toBe('300');
|
||||
expect(screen.getByText(xframe.embedHint)).toBeInTheDocument();
|
||||
|
||||
fireEvent.change(url, { target: { value: 'https://b.de/' } });
|
||||
fireEvent.blur(url);
|
||||
await vi.waitFor(() => expect(onWidgetUpdate).toHaveBeenCalledWith('x1', { url: 'https://b.de/' }));
|
||||
expect(updateWidgetConfig).toHaveBeenCalledTimes(1);
|
||||
expect(updateWidgetConfig).toHaveBeenCalledWith('x1', { url: 'https://b.de/' });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user