feat: 开源蟹蟹输入RTOS适配改版并采用MIT商用许可
这个提交包含在:
当前提交
29374caffd
116 个文件已更改
+351523
没有与搜索条件相匹配的文件
@@ -0,0 +1,71 @@
|
||||
"""Capture all keyboard layouts and check clipping, round bounds and dark edge gaps."""
|
||||
import argparse,datetime,importlib.util,json,math,pathlib,time
|
||||
from PIL import Image
|
||||
import layout
|
||||
|
||||
APP=pathlib.Path(__file__).resolve().parents[1]
|
||||
spec=importlib.util.spec_from_file_location('native',APP/'tests/native.py')
|
||||
native=importlib.util.module_from_spec(spec);spec.loader.exec_module(native);emu=native.emu
|
||||
|
||||
def dark_edges(path,profile):
|
||||
im=Image.open(path).convert('RGB');points=[]
|
||||
if profile.startswith('round'):
|
||||
# 466px screen inside the vendor's 624px hardware skin. Stay 7px inside its edge.
|
||||
im=im.crop((70,79,536,545))
|
||||
for y in range(466):
|
||||
for x in range(466):
|
||||
radius=math.hypot(x-233,y-233)
|
||||
if 224<=radius<=226 and max(im.getpixel((x,y)))<80:points.append([x,y])
|
||||
else:
|
||||
for y in range(4,446):
|
||||
for x in [3,386]:
|
||||
if max(im.getpixel((x,y)))<80:points.append([x,y])
|
||||
for x in range(4,386):
|
||||
for y in [3,446]:
|
||||
if max(im.getpixel((x,y)))<80:points.append([x,y])
|
||||
return len(points)
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--work',type=pathlib.Path,required=True);parser.add_argument('--output',type=pathlib.Path,required=True)
|
||||
parser.add_argument('--profiles',nargs='+',default=emu.PROFILES);args=parser.parse_args();args.output.mkdir(parents=True,exist_ok=True)
|
||||
report={'recorded_at':datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=8))).isoformat(),'artifacts':{},'screens':[]}
|
||||
def capture(profile,name):
|
||||
# Inspector history can associate the new widget tree with the preceding
|
||||
# back buffer on an otherwise idle page. Request two real redraws, restore
|
||||
# the original caption, then retain only the fresh native frame.
|
||||
emu.evaluate("var view=require('@system.router').default.getPages().slice(-1)[0];var captionKey=typeof view.hint==='string'?'hint':'status';var oldCaption=view[captionKey];view[captionKey]=oldCaption+' '")
|
||||
time.sleep(.2)
|
||||
emu.evaluate("view[captionKey]=oldCaption")
|
||||
time.sleep(.4);emu.snapshot(profile+'-'+name,args.output)
|
||||
time.sleep(.3);emu.snapshot(profile+'-'+name,args.output)
|
||||
result=layout.inspect(args.output/(profile+'-'+name+'.tree.json'),profile)
|
||||
result['dark_edge_pixels']=dark_edges(args.output/(profile+'-'+name+'.png'),profile)
|
||||
result['passed']=result['passed'] and result['dark_edge_pixels']==0
|
||||
result.update(profile=profile,screen=name);report['screens'].append(result)
|
||||
native.save(args.output/'visual-results.json',report)
|
||||
print(json.dumps(result,ensure_ascii=False),flush=True)
|
||||
if not result['passed']:raise RuntimeError('Visual regression: '+profile+'-'+name)
|
||||
for profile in args.profiles:
|
||||
process,artifacts=emu.start(profile,args.work,'inputmethod');report['artifacts'][profile]=artifacts
|
||||
try:
|
||||
capture(profile,'home')
|
||||
emu.evaluate("var r=require('@system.router').default,t=require('@system.test').default;var root=r.getPage(0);t.getByClass('document').click()")
|
||||
time.sleep(1);emu.evaluate("var p=r.getPage(1);p.composition='64426';p.schedule()")
|
||||
time.sleep(.5);capture(profile,'t9')
|
||||
emu.evaluate("p.composition='shi';p.mode='py';p.renderKeys();p.schedule()")
|
||||
time.sleep(.5);capture(profile,'pinyin')
|
||||
emu.evaluate("p.expand()");capture(profile,'candidates')
|
||||
emu.evaluate("p.showTools()");capture(profile,'tools')
|
||||
emu.evaluate("p.composition='';p.setMode('14');p.composition='c3754';p.schedule()")
|
||||
time.sleep(.5);capture(profile,'14-key')
|
||||
emu.evaluate("p.expand()");capture(profile,'14-candidates')
|
||||
for mode in ['en','num','sym']:
|
||||
emu.evaluate("p.composition='';p.setMode("+json.dumps(mode)+")")
|
||||
capture(profile,mode)
|
||||
emu.evaluate("p.symbols()");capture(profile,'sym2')
|
||||
finally:
|
||||
if process.poll()is None:process.terminate()
|
||||
process.wait(timeout=10);process.stdin.close()
|
||||
report['passed']=all(screen['passed']for screen in report['screens']);native.save(args.output/'visual-results.json',report)
|
||||
|
||||
if __name__=='__main__':main()
|
||||
在新工单中引用
屏蔽一个用户