from playwright.sync_api import sync_playwright import json with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() calls = [] rows = [dict(nome=f'Servo {i+1}',canal=i,minimo=1400,maximo=1600,centro=1500) for i in range(6)] def handle(route): if route.request.method == 'POST': calls.append((route.request.url, route.request.post_data_json)) route.fulfill(content_type='application/json',body=json.dumps(dict(disponivel=True,erro='',servos=rows,ativos=[]))) page.route('**/servos/status', handle) page.route('**/servos/mover', handle) page.route('**/servos/parar', handle) page.goto('http://192.168.1.35:8100/servos') page.wait_for_selector('.card') live = page.locator('#live') assert live.count() == 1, 'Modo ao vivo ausente' assert not live.is_checked() slider = page.locator('input[type=range]').first slider.evaluate("e=>{e.value=1450;e.dispatchEvent(new Event('input'))}") page.wait_for_timeout(200) assert calls == [] live.check() assert calls == [], 'Ativar modo não deve mover' slider.evaluate("e=>{for(let i=0;i<30;i++){e.value=1400+(i%20)*5;e.dispatchEvent(new Event('input'))}e.value=1600;e.dispatchEvent(new Event('input'))}") page.wait_for_timeout(500) moves = [data for url,data in calls if url.endswith('/mover')] assert 1 <= len(moves) <= 6, len(moves) assert moves[-1] == dict(indice=0,pulso=1600) page.locator('#stop').click() page.wait_for_timeout(200) assert not live.is_checked() assert calls[-1][0].endswith('/parar') count = len(calls) slider.evaluate("e=>{e.value=1400;e.dispatchEvent(new Event('input'))}") page.wait_for_timeout(200) assert len(calls) == count page.locator('input[type=text]').first.fill('Teste') assert live.is_disabled() print('OK: live opt-in, limite de envio, último valor, parada cancela fila, alterações bloqueiam; hardware simulado') browser.close()