Created
November 15, 2024 17:50
-
-
Save stelar7/3b25202ccaaa466d5b8efeb0aef3ffd5 to your computer and use it in GitHub Desktop.
requires imagemagick :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from collections import namedtuple | |
from pathlib import Path | |
import base64 | |
import csv | |
import httplib2 | |
import json | |
import os | |
import subprocess | |
TestInstance = namedtuple('TestInstance', ['input', 'expected']) | |
github_bearer_token = "bearer ASDF1234FDSA4321" | |
class WebDriver: | |
baseUrl = "http://0.0.0.0:4444" | |
sessionId = None | |
def makeGetRequest(self, url): | |
_, content = httplib2.Http().request(self.baseUrl + url) | |
return content.decode("utf-8") | |
def makePostRequest(self, url, data): | |
_, content = httplib2.Http().request(self.baseUrl + url, "POST", body=json.dumps(data), headers={"Content-Type": "application/json"}) | |
return content.decode("utf-8") | |
def createSession(self): | |
session = self.makePostRequest("/session", { | |
"capabilities": { | |
"alwaysMatch": { | |
"serenity:ladybird": { | |
"headless": True, | |
} | |
} | |
} | |
}) | |
self.sessionId = json.loads(session)["value"]["sessionId"] | |
def setWindowSize(self, width, height): | |
self.makePostRequest("/session/" + self.sessionId + "/window/rect", { | |
"width": width, | |
"height": height | |
}) | |
def navigateTo(self, url): | |
self.makePostRequest("/session/" + self.sessionId + "/url", { | |
"url": url | |
}) | |
def takeScreenshot(self): | |
screenshot = self.makeGetRequest("/session/" + self.sessionId + "/screenshot") | |
screenshotBase64 = json.loads(screenshot)["value"] | |
return base64.b64decode(screenshotBase64) | |
def loadTests(root): | |
tests = [] | |
def handleDirectory(data): | |
for entry in data: | |
if entry["type"] == "file": | |
if entry["name"].endswith(".svg"): | |
svgPath = entry["download_url"] | |
pngPath = svgPath.replace(".svg", ".png") | |
tests.append(TestInstance(svgPath, pngPath)) | |
elif entry["type"] == "dir": | |
print("Loading tests in " + entry["path"]) | |
_, content = httplib2.Http(cache="github-cache").request(entry["url"], "GET", headers={"Authorization": github_bearer_token}) | |
handleDirectory(json.loads(content)) | |
_, content = httplib2.Http(cache="github-cache").request(root, "GET", headers={"Authorization": github_bearer_token}) | |
handleDirectory(json.loads(content)) | |
return tests | |
def runTest(test): | |
# Ensure output folder exists and setup variables | |
baseUrl = "/main/tests/" | |
basePath = "Tests/resvg/" + test.input[test.input.index(baseUrl) + len(baseUrl):] | |
filename = test.input.split("/")[-1] | |
saveTo = '/'.join(basePath.split("/")[0:-1]) | |
saveTo = saveTo.replace(baseUrl, "") | |
os.makedirs(saveTo, exist_ok=True) | |
inputFile = Path(saveTo + "/" + filename.replace(".svg", ".ladybird.png")).absolute() | |
outputFile = Path(saveTo + "/" + filename.replace(".svg", ".png")).absolute() | |
diffFile = Path(saveTo + "/" + filename.replace(".svg", ".diff.png")).absolute() | |
print("Running test for " + test.input) | |
# Navigate to SVG file if it doesnt exist | |
if not os.path.exists(inputFile): | |
driver.navigateTo(test.input) | |
# Take screenshot | |
screenshotBytes = driver.takeScreenshot() | |
with open(inputFile, "wb") as f: | |
f.write(screenshotBytes) | |
# Note: We need to screenshot the PNG to ensure the transparency is the same | |
# FIXME: Allow transparent windows? | |
# Navigate to PNG file if it doesnt exist | |
if not os.path.exists(outputFile): | |
driver.navigateTo(test.expected) | |
# Take screenshot | |
screenshotBytes = driver.takeScreenshot() | |
with open(outputFile, "wb") as f: | |
f.write(screenshotBytes) | |
# Get absolute difference | |
result = subprocess.run(["compare", "-metric", "AE", inputFile, outputFile, diffFile], capture_output=True, text=True) | |
maxScore = 500 * 500 | |
resultScore = maxScore - int(result.stderr) | |
percentage = (resultScore / maxScore) * 100 | |
with open("results.csv", "a") as f: | |
writer = csv.writer(f) | |
writer.writerow([test.input, resultScore, maxScore, percentage]) | |
print("Score for " + str(outputFile) + ": " + str(resultScore) + " / " + str(maxScore) + " (" + str(percentage) + "%)") | |
if __name__ == "__main__": | |
driver = WebDriver() | |
# Start a new session with the correct screen size | |
driver.createSession() | |
driver.setWindowSize(500, 500) | |
tests = loadTests("https://api.github.com/repos/linebender/resvg-test-suite/contents/tests") | |
# Reset results file | |
os.remove("results.csv") | |
with open("results.csv", "a") as f: | |
writer = csv.writer(f) | |
writer.writerow(["File", "Score", "Max", "Percentage"]) | |
for test in tests: | |
runTest(test) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment