added very basic web replayer

This commit is contained in:
Faraphel 2024-01-02 13:55:22 +01:00
parent 30dd5410f0
commit 12617346d7
4 changed files with 162 additions and 0 deletions

21
tools/web_replay/main.py Normal file
View file

@ -0,0 +1,21 @@
import sys
from PyQt6.QtWidgets import QApplication
from tools.web_replay.ui import ReplayWindow
if __name__ == "__main__":
# create the application
application = QApplication(sys.argv)
from source.utils import compress
with open(r"C:\Users\RC606\Downloads\41a6268b-72e5-47a9-8106-6c15a0be366e.rsl", "rb") as file:
data = compress.uncompress_data(file.read())
# create the window
window = ReplayWindow(data["surveys"]["mission-gift-card"]["event"])
window.show()
# start the application
application.exec()

View file

@ -0,0 +1,121 @@
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)

View file

@ -0,0 +1,18 @@
from PyQt6.QtCore import QTimer
from PyQt6.QtWidgets import QMainWindow
from tools.web_replay.ui import ReplayEngine
class ReplayWindow(QMainWindow):
def __init__(self, replay_data: dict):
super().__init__()
self.replay_engine = ReplayEngine(replay_data)
self.setCentralWidget(self.replay_engine)
# TODO: TEST REMOVE
self.timer = QTimer()
self.timer.setInterval(10)
self.timer.timeout.connect(self.replay_engine.next) # NOQA: connect exist
self.timer.start()

View file

@ -0,0 +1,2 @@
from .ReplayEngine import ReplayEngine
from .ReplayWindow import ReplayWindow