M1-Survey-Engine/tools/web_replay/ui/ReplayEngine.py

121 lines
4.1 KiB
Python

from PyQt6.QtCore import Qt, QUrl, QSize, QPointF
from PyQt6.QtGui import QKeyEvent, QMouseEvent
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QApplication
class ReplayEngine(QWidget):
"""
This widget allow to replay some event that occurred on a web page
"""
def __init__(self, replay_data: dict):
super().__init__()
self.replay_data = replay_data
self.iterator = iter(self.replay_data)
# layout
self._layout = QVBoxLayout()
self.setLayout(self._layout)
# cursor
self.cursor = QLabel(self)
self.cursor.setFixedSize(20, 20)
self.cursor.setStyleSheet("background-color: red; border-radius: 10px;")
# web
self.web = QWebEngineView()
self._layout.addWidget(self.web)
def run_event(self, event: dict):
match event["type"]:
case "success":
# success event
print(f"success ! ({event['time']}s)")
case "url":
# changing url event
self.web.setUrl(QUrl(event["url"]))
case "resize":
# changing widget size event
self.web.resize(QSize(*event["size"]))
# TODO: better way ?
self.window().resize(QSize(*event["size"]))
case "keyboard_press":
# keyboard key pressed event
key = QKeyEvent(
QKeyEvent.Type.KeyPress,
event["key"],
Qt.KeyboardModifier.NoModifier
)
QApplication.sendEvent(self.web.page(), key)
case "keyboard_release":
# keyboard key released event
key = QKeyEvent(
QKeyEvent.Type.KeyRelease,
event["key"],
Qt.KeyboardModifier.NoModifier
)
QApplication.sendEvent(self.web.page(), key)
case "mouse_press":
# mouse pressed event
key = QMouseEvent(
QMouseEvent.Type.KeyPress,
QPointF(*event["position"]),
Qt.MouseButton(event["button"]),
Qt.MouseButton.NoButton,
Qt.KeyboardModifier.NoModifier
)
QApplication.sendEvent(self.web.page(), key)
case "mouse_release":
# mouse pressed event
key = QMouseEvent(
QMouseEvent.Type.KeyRelease,
QPointF(*event["position"]),
Qt.MouseButton(event["button"]),
Qt.MouseButton.NoButton,
Qt.KeyboardModifier.NoModifier
)
QApplication.sendEvent(self.web.page(), key)
# NOTE: this event is redundant
# case "mouse_double_click":
# # mouse double-clicked event
# key = QMouseEvent(QMouseEvent.Type.MouseButtonDblClick, event["position"], event["button"])
# QApplication.sendEvent(self.page(), key)
case "mouse_move":
# mouse moved event
key = QMouseEvent(
QMouseEvent.Type.KeyRelease,
QPointF(*event["position"]),
Qt.MouseButton.NoButton,
Qt.MouseButton.NoButton,
Qt.KeyboardModifier.NoModifier
)
QApplication.sendEvent(self.web.page(), key)
# move the fake cursor
self.cursor.move(QPointF(*event["position"]).toPoint() - self.cursor.rect().center())
self.cursor.raise_()
case "scroll":
# scroll event
x, y = event["position"]
self.web.page().runJavaScript(f"window.scrollTo({x}, {y});")
def next(self):
try:
event = next(self.iterator)
except StopIteration:
print("end of record")
return
self.run_event(event)