metis-desk/scripts/resource-image-ui-checks.py

20 lines
3.0 KiB
Python
Raw Normal View History

"""Comprueba el control PNG compartido mediante el navegador MCP de la auditoría aislada."""
import base64
import json
from pathlib import Path
def assert_list_icons(client, code, selector='[data-software-product] img', minimum=1):
code(client, "await page.locator(" + json.dumps(selector) + ").first().scrollIntoViewIfNeeded(); await page.waitForFunction(({selector,minimum})=>{const images=[...document.querySelectorAll(selector)].slice(0,minimum);return images.length===minimum&&images.every(image=>image.complete&&image.naturalWidth>0&&image.getAttribute('src').startsWith('data:image/png;base64,'));},{selector:" + json.dumps(selector) + ",minimum:" + str(minimum) + "}); if(await page.locator('body').innerText().then(text=>text.includes('data:image/png;base64,')))throw Error('Base64 visible como texto');")
def verify(client, code):
icon = Path(__file__).resolve().parent.parent / 'apps/server/data/resource-icons/windows-11.png'
encoded = base64.b64encode(icon.read_bytes()).decode('ascii')
valid = "{name:'icon.png',mimeType:'image/png',buffer:Buffer.from(" + json.dumps(encoded) + ",'base64')}"
code(client, "await page.getByLabel('Icono',{exact:true}).setInputFiles({name:'invalid.jpg',mimeType:'image/jpeg',buffer:Buffer.from('invalid')}); await page.getByText('Selecciona un PNG válido de hasta 512 × 512 píxeles y 2 MiB.',{exact:true}).waitFor(); if(await page.getByLabel('Icono',{exact:true}).evaluate(e=>e.checkValidity()))throw Error('Imagen inválida aceptada');")
code(client, "await page.getByLabel('Icono',{exact:true}).setInputFiles(" + valid + "); await page.getByAltText('Vista previa de Icono',{exact:true}).waitFor(); await page.getByAltText('Vista previa de Icono',{exact:true}).scrollIntoViewIfNeeded(); await page.waitForFunction(()=>[...document.querySelectorAll('dialog img,[role=dialog] img')].some(e=>e.complete&&e.naturalWidth>0));")
code(client, "await page.getByLabel('Icono',{exact:true}).setInputFiles({name:'corrupt.png',mimeType:'image/png',buffer:Buffer.from('invalid')}); await page.getByText('Selecciona un PNG válido de hasta 512 × 512 píxeles y 2 MiB.',{exact:true}).waitFor(); if(!await page.getByAltText('Vista previa de Icono',{exact:true}).count())throw Error('Se perdió el icono anterior'); await page.getByRole('button',{name:'Quitar imagen',exact:true}).focus(); await page.keyboard.press('Space'); await page.getByAltText('Vista previa de Icono',{exact:true}).waitFor({state:'detached'}); if(!await page.getByLabel('Icono',{exact:true}).evaluate(e=>e.checkValidity()))throw Error('Error no retirado');")
code(client, "await page.getByLabel('Icono',{exact:true}).setInputFiles(" + valid + "); await page.getByAltText('Vista previa de Icono',{exact:true}).waitFor(); if(!await page.getByLabel('Icono',{exact:true}).evaluate(e=>e.checkValidity()))throw Error('PNG válido bloqueado');")
return ['png-upload-preview', 'invalid-format-blocked', 'invalid-png-blocked', 'previous-image-preserved', 'remove-with-keyboard', 'replace-png']