Skip to content

Instantly share code, notes, and snippets.

@stelar7
Created November 15, 2024 17:50
Show Gist options
  • Save stelar7/3b25202ccaaa466d5b8efeb0aef3ffd5 to your computer and use it in GitHub Desktop.
Save stelar7/3b25202ccaaa466d5b8efeb0aef3ffd5 to your computer and use it in GitHub Desktop.
requires imagemagick :)
#!/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