121 lines
4.1 KiB
Python
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)
|