#!/usr/bin/python3 # -*- coding: utf-8 -*- # This test runs a local copy of https://html5test.com/ and # checks the resulting score against the expected result. # The score may get higher with newer versions of firefox. # The local copy of the test was cloned from # https://github.com/WebPlatformTest/HTML5test.git import http.server import os import re import sys import threading from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC if __name__ == '__main__': options = webdriver.firefox.options.Options() options.binary_location = "/usr/bin/firefox" options.add_argument("-headless") driver = webdriver.Firefox(options=options) tests_dir = os.path.dirname(os.path.realpath(__file__)) html5test_dir = os.path.join(tests_dir, "data", "HTML5test") os.chdir(html5test_dir) handler = http.server.SimpleHTTPRequestHandler server = http.server.HTTPServer(("", 0), handler) server.allow_reuse_address = True server_thread = threading.Thread(target=server.serve_forever) server_thread.start() driver.get("http://localhost:{}/".format(server.server_port)) WebDriverWait(driver, 10).until( EC.text_to_be_present_in_element( (By.ID, "score"), "YOUR BROWSER SCORES")) score = driver.find_element_by_id("score").text match = re.search("YOUR BROWSER SCORES (\d+) OUT OF (\d+) POINTS", score) assert match is not None score = (int(match.group(1)), int(match.group(2))) expected_score = (508, 555) sys.stderr.flush() print("Score: {}/{}".format(score[0], score[1])) expected = [ ("row-parsing.doctype", "Yes"), ("row-parsing.tokenizer", "Yes"), ("row-parsing.tree", "Yes"), ("row-parsing.svg", "Yes"), ("row-parsing.mathml", "Yes"), ("row-elements.dataset", "Yes"), ("row-elements.section", "Yes"), ("row-elements.section.section", "Yes"), ("row-elements.section.nav", "Yes"), ("row-elements.section.article", "Yes"), ("row-elements.section.aside", "Yes"), ("row-elements.section.header", "Yes"), ("row-elements.section.footer", "Yes"), ("row-elements.grouping", "Yes"), ("row-elements.grouping.main", "Yes"), ("row-elements.grouping.figure", "Yes"), ("row-elements.grouping.figcaption", "Yes"), ("row-elements.grouping.ol", "Yes"), ("row-elements.semantic", "Yes"), ("row-elements.semantic.download", "Yes"), ("row-elements.semantic.ping", "Yes"), ("row-elements.semantic.mark", "Yes"), ("row-elements.semantic.ruby", "Yes"), ("row-elements.semantic.time", "Yes"), ("row-elements.semantic.data", "Yes"), ("row-elements.semantic.wbr", "Yes"), ("row-elements.interactive", "Partial"), ("row-elements.interactive.details", "Yes"), ("row-elements.interactive.summary", "Yes"), ("row-elements.interactive.menutoolbar", "No"), ("row-elements.interactive.menucontext", "No"), ("row-elements.interactive.dialog", "Yes"), ("row-elements.hidden", "Yes"), ("row-elements.dynamic", "Yes"), ("row-elements.dynamic.outerHTML", "Yes"), ("row-elements.dynamic.insertAdjacentHTML", "Yes"), ("row-form.text", "Yes"), ("row-form.text.element", "Yes"), ("row-form.text.selection", "Yes"), ("row-form.search", "Yes"), ("row-form.search.element", "Yes"), ("row-form.tel", "Yes"), ("row-form.tel.element", "Yes"), ("row-form.url", "Yes"), ("row-form.url.element", "Yes"), ("row-form.url.validation", "Yes"), ("row-form.email", "Yes"), ("row-form.email.element", "Yes"), ("row-form.email.validation", "Yes"), ("row-form.date", "Yes"), ("row-form.date.element", "Yes"), ("row-form.date.ui", "Yes"), ("row-form.date.sanitization", "Yes"), ("row-form.date.min", "Yes"), ("row-form.date.max", "Yes"), ("row-form.date.step", "Yes"), ("row-form.date.stepDown", "Yes"), ("row-form.date.stepUp", "Yes"), ("row-form.date.valueAsDate", "Yes"), ("row-form.date.valueAsNumber", "Yes"), ("row-form.month", "No"), ("row-form.month.element", "No"), ("row-form.month.ui", "No"), ("row-form.month.sanitization", "No"), ("row-form.month.min", "No"), ("row-form.month.max", "No"), ("row-form.month.step", "No"), ("row-form.month.stepDown", "No"), ("row-form.month.stepUp", "No"), ("row-form.month.valueAsDate", "No"), ("row-form.month.valueAsNumber", "No"), ("row-form.week", "No"), ("row-form.week.element", "No"), ("row-form.week.ui", "No"), ("row-form.week.sanitization", "No"), ("row-form.week.min", "No"), ("row-form.week.max", "No"), ("row-form.week.step", "No"), ("row-form.week.stepDown", "No"), ("row-form.week.stepUp", "No"), ("row-form.week.valueAsDate", "No"), ("row-form.week.valueAsNumber", "No"), ("row-form.time", "Yes"), ("row-form.time.element", "Yes"), ("row-form.time.ui", "Yes"), ("row-form.time.sanitization", "Yes"), ("row-form.time.min", "Yes"), ("row-form.time.max", "Yes"), ("row-form.time.step", "Yes"), ("row-form.time.stepDown", "Yes"), ("row-form.time.stepUp", "Yes"), ("row-form.time.valueAsDate", "Yes"), ("row-form.time.valueAsNumber", "Yes"), ("row-form.datetime-local", "Yes"), ("row-form.datetime-local.element", "Yes"), ("row-form.datetime-local.ui", "Yes"), ("row-form.datetime-local.sanitization", "Yes"), ("row-form.datetime-local.min", "Yes"), ("row-form.datetime-local.max", "Yes"), ("row-form.datetime-local.step", "Yes"), ("row-form.datetime-local.stepDown", "Yes"), ("row-form.datetime-local.stepUp", "Yes"), ("row-form.datetime-local.valueAsNumber", "Yes"), ("row-form.number", "Yes"), ("row-form.number.element", "Yes"), ("row-form.number.ui", "Yes"), ("row-form.number.sanitization", "Yes"), ("row-form.number.validation", "Yes"), ("row-form.number.min", "Yes"), ("row-form.number.max", "Yes"), ("row-form.number.step", "Yes"), ("row-form.number.stepDown", "Yes"), ("row-form.number.stepUp", "Yes"), ("row-form.number.valueAsNumber", "Yes"), ("row-form.range", "Yes"), ("row-form.range.element", "Yes"), ("row-form.range.ui", "Yes"), ("row-form.range.sanitization", "Yes"), ("row-form.range.min", "Yes"), ("row-form.range.max", "Yes"), ("row-form.range.step", "Yes"), ("row-form.range.stepDown", "Yes"), ("row-form.range.stepUp", "Yes"), ("row-form.range.valueAsNumber", "Yes"), ("row-form.color", "Yes"), ("row-form.color.element", "Yes"), ("row-form.color.ui", "Yes"), ("row-form.color.sanitization", "Yes"), ("row-form.checkbox", "Yes"), ("row-form.checkbox.element", "Yes"), ("row-form.checkbox.indeterminate", "Yes"), ("row-form.image", "Yes"), ("row-form.image.element", "Yes"), ("row-form.image.width", "Yes"), ("row-form.image.height", "Yes"), ("row-form.file", "Partial"), ("row-form.file.element", "Yes"), ("row-form.file.files", "Yes"), ("row-form.file.directory", "No"), ("row-form.textarea", "Yes"), ("row-form.textarea.element", "Yes"), ("row-form.textarea.maxlength", "Yes"), ("row-form.textarea.wrap", "Yes"), ("row-form.select", "Yes"), ("row-form.select.element", "Yes"), ("row-form.select.required", "Yes"), ("row-form.fieldset", "Yes"), ("row-form.fieldset.element", "Yes"), ("row-form.fieldset.elements", "Yes"), ("row-form.fieldset.disabled", "Yes"), ("row-form.datalist", "Yes"), ("row-form.datalist.element", "Yes"), ("row-form.datalist.list", "Yes"), ("row-form.output", "Yes"), ("row-form.output.element", "Yes"), ("row-form.progress", "Yes"), ("row-form.progress.element", "Yes"), ("row-form.meter", "Yes"), ("row-form.meter.element", "Yes"), ("row-form.validation", "Yes"), ("row-form.validation.pattern", "Yes"), ("row-form.validation.required", "Yes"), ("row-form.association", "Yes"), ("row-form.association.control", "Yes"), ("row-form.association.form", "Yes"), ("row-form.association.formAction", "Yes"), ("row-form.association.formEnctype", "Yes"), ("row-form.association.formMethod", "Yes"), ("row-form.association.formNoValidate", "Yes"), ("row-form.association.formTarget", "Yes"), ("row-form.association.labels", "Yes"), ("row-form.other", "Partial"), ("row-form.other.autofocus", "Yes"), ("row-form.other.autocomplete", "Yes"), ("row-form.other.placeholder", "Yes"), ("row-form.other.multiple", "Yes"), ("row-form.other.dirname", "No"), ("row-form.selectors", "Yes"), ("row-form.selectors.valid", "Yes"), ("row-form.selectors.invalid", "Yes"), ("row-form.selectors.optional", "Yes"), ("row-form.selectors.required", "Yes"), ("row-form.selectors.in-range", "Yes"), ("row-form.selectors.out-of-range", "Yes"), ("row-form.selectors.read-write", "Yes"), ("row-form.selectors.read-only", "Yes"), ("row-form.events", "Yes"), ("row-form.events.oninput", "Yes"), ("row-form.events.onchange", "Yes"), ("row-form.events.oninvalid", "Yes"), ("row-form.formvalidation", "Yes"), ("row-form.formvalidation.checkValidity", "Yes"), ("row-form.formvalidation.noValidate", "Yes"), ("row-components.custom", "No"), ("row-components.shadowdom", "Yes"), ("row-components.template", "Yes"), ("row-components.imports", "No"), ("row-location.geolocation", "Yes"), ("row-location.orientation", "Yes"), ("row-location.motion", "Yes"), ("row-output.requestFullScreen", "Yes"), ("row-output.notifications", "Yes"), ("row-input.getGamepads", "Yes"), ("row-input.pointerevents", "Yes"), ("row-input.pointerLock", "Yes"), ("row-communication.eventSource", "Yes"), ("row-communication.beacon", "Yes"), ("row-communication.fetch", "Yes"), ("row-communication.xmlhttprequest2.upload", "Yes"), ("row-communication.xmlhttprequest2.response", "Yes"), ("row-communication.xmlhttprequest2.response.text", "Yes"), ("row-communication.xmlhttprequest2.response.document", "Yes"), ("row-communication.xmlhttprequest2.response.array", "Yes"), ("row-communication.xmlhttprequest2.response.blob", "Yes"), ("row-communication.websocket.basic", "Yes"), ("row-communication.websocket.binary", "Yes"), ("row-streams.readable", "Yes"), ("row-streams.writeable", "No"), ("row-rtc.webrtc", "Yes"), ("row-rtc.objectrtc", "No"), ("row-rtc.datachannel", "Yes"), ("row-media.getUserMedia", "Yes"), ("row-media.getDisplayMedia", "Yes"), ("row-media.enumerateDevices", "Yes"), ("row-rtc.recorder", "Yes"), ("row-interaction.dragdrop.attributes", "Partial"), ("row-interaction.dragdrop.attributes.draggable", "Yes"), ("row-interaction.dragdrop.attributes.dropzone", "No"), ("row-interaction.dragdrop.events", "Yes"), ("row-interaction.dragdrop.events.ondrag", "Yes"), ("row-interaction.dragdrop.events.ondragstart", "Yes"), ("row-interaction.dragdrop.events.ondragenter", "Yes"), ("row-interaction.dragdrop.events.ondragover", "Yes"), ("row-interaction.dragdrop.events.ondragleave", "Yes"), ("row-interaction.dragdrop.events.ondragend", "Yes"), ("row-interaction.dragdrop.events.ondrop", "Yes"), ("row-interaction.editing.elements", "Yes"), ("row-interaction.editing.elements.contentEditable", "Yes"), ("row-interaction.editing.elements.isContentEditable", "Yes"), ("row-interaction.editing.documents", "Yes"), ("row-interaction.editing.documents.designMode", "Yes"), ("row-interaction.editing.selectors", "Yes"), ("row-interaction.editing.selectors.read-write", "Yes"), ("row-interaction.editing.selectors.read-only", "Yes"), ("row-interaction.editing.apis", "Yes"), ("row-interaction.editing.apis.execCommand", "Yes"), ("row-interaction.editing.apis.queryCommandEnabled", "Yes"), ("row-interaction.editing.apis.queryCommandIndeterm", "Yes"), ("row-interaction.editing.apis.queryCommandState", "Yes"), ("row-interaction.editing.apis.queryCommandSupported", "Yes"), ("row-interaction.editing.apis.queryCommandValue", "Yes"), ("row-interaction.clipboard", "Yes"), ("row-interaction.spellcheck", "Yes"), ("row-performance.worker", "Yes"), ("row-performance.sharedWorker", "Yes"), ("row-performance.requestIdleCallback", "Yes"), ("row-security.crypto", "Yes"), ("row-security.csp10", "No"), ("row-security.csp11", "Yes"), ("row-security.cors", "Yes"), ("row-security.integrity", "Yes"), ("row-security.postMessage", "Yes"), ("row-security.authentication", "No"), ("row-security.credential", "Yes"), ("row-security.sandbox", "Yes"), ("row-security.srcdoc", "Yes"), ("row-payments.payments", "No"), ("row-video.element", "Yes"), ("row-video.subtitle", "Yes"), ("row-video.audiotracks", "No"), ("row-video.videotracks", "No"), ("row-video.poster", "Yes"), ("row-video.canplaytype", "Yes"), ("row-video.codecs.mp4.mpeg4", "No"), ("row-video.codecs.mp4.h264", "Yes"), ("row-video.codecs.mp4.h265", "No"), ("row-video.codecs.ogg.theora", "Yes"), ("row-video.codecs.webm.vp8", "Yes"), ("row-video.codecs.webm.vp9", "Yes"), ("row-audio.element", "Yes"), ("row-audio.loop", "Yes"), ("row-audio.preload", "Yes"), ("row-audio.webaudio", "Yes"), ("row-audio.speechrecognition", "No"), ("row-audio.speechsynthesis", "No"), ("row-audio.codecs.pcm", "Yes"), ("row-audio.codecs.mp3", "Yes"), ("row-audio.codecs.mp4.aac", "Yes"), ("row-audio.codecs.mp4.ac3", "No"), ("row-audio.codecs.mp4.ec3", "No"), ("row-audio.codecs.ogg.vorbis", "Yes"), ("row-audio.codecs.ogg.opus", "Yes"), ("row-audio.codecs.webm.vorbis", "Yes"), ("row-audio.codecs.webm.opus", "Yes"), ("row-streaming.mediasource", "Yes"), ("row-streaming.drm", "Yes"), ("row-streaming.type.dash", "No"), ("row-streaming.type.hls", "No"), ("row-streaming.video.codecs", "Partial"), ("row-streaming.video.codecs.mp4.h264", "Yes"), ("row-streaming.video.codecs.mp4.h265", "No"), ("row-streaming.video.codecs.ts.h264", "No"), ("row-streaming.video.codecs.ts.h265", "No"), ("row-streaming.video.codecs.webm.vp8", "Yes"), ("row-streaming.video.codecs.webm.vp9", "Yes"), ("row-streaming.audio.codecs", "Partial"), ("row-streaming.audio.codecs.mp4.aac", "Yes"), ("row-streaming.audio.codecs.mp4.ac3", "No"), ("row-streaming.audio.codecs.mp4.ec3", "No"), ("row-streaming.audio.codecs.ts.aac", "No"), ("row-streaming.audio.codecs.ts.ac3", "No"), ("row-streaming.audio.codecs.ts.ec3", "No"), ("row-streaming.audio.codecs.webm.vorbis", "Yes"), ("row-streaming.audio.codecs.webm.opus", "Yes"), ("row-responsive.picture", "Yes"), ("row-responsive.srcset", "Yes"), ("row-responsive.sizes", "Yes"), ("row-canvas.context", "Yes"), ("row-canvas.text", "Yes"), ("row-canvas.path", "Yes"), ("row-canvas.ellipse", "Yes"), ("row-canvas.dashed", "Yes"), ("row-canvas.focusring", "Yes"), ("row-canvas.hittest", "No"), ("row-canvas.blending", "Yes"), ("row-canvas.png", "Yes"), ("row-canvas.jpeg", "Yes"), ("row-canvas.jpegxr", "No"), ("row-canvas.webp", "Yes"), ("row-3d.webgl", "Yes"), ("row-3d.webgl2", "Yes"), ("row-3d.webvr", "No"), ("row-animation.webanimation", "Yes"), ("row-animation.requestAnimationFrame", "Yes"), ("row-offline.applicationCache", "No"), ("row-offline.serviceWorkers", "Yes"), ("row-offline.pushMessages", "Yes"), ("row-offline.registerProtocolHandler", "Yes"), ("row-offline.registerContentHandler", "No"), ("row-storage.sessionStorage", "Yes"), ("row-storage.localStorage", "Yes"), ("row-storage.indexedDB.basic", "Yes"), ("row-storage.indexedDB.blob", "Yes"), ("row-storage.indexedDB.arraybuffer", "Yes"), ("row-storage.sqlDatabase", "No"), ("row-files.fileReader", "Yes"), ("row-files.fileReader.blob", "Yes"), ("row-files.fileReader.dataURL", "Yes"), ("row-files.fileReader.arraybuffer", "Yes"), ("row-files.fileReader.objectURL", "Yes"), ("row-files.getFileSystem", "No"), ("row-files.fileSystem", "No"), ("row-scripting.async", "Yes"), ("row-scripting.defer", "Yes"), ("row-scripting.executionevents", "Yes"), ("row-scripting.onerror", "Yes"), ("row-scripting.es5.json", "Yes"), ("row-scripting.es6.modules", "Yes"), ("row-scripting.es6.class", "Yes"), ("row-scripting.es6.arrow", "Yes"), ("row-scripting.es6.promises", "Yes"), ("row-scripting.es6.template", "Yes"), ("row-scripting.es6.datatypes", "Yes"), ("row-scripting.es6.i18n", "Yes"), ("row-scripting.es7.async", "Yes"), ("row-scripting.base64", "Yes"), ("row-scripting.mutationObserver", "Yes"), ("row-scripting.url", "Yes"), ("row-scripting.encoding", "Yes"), ("row-other.history", "Yes"), ("row-other.pagevisiblity", "Yes"), ("row-other.getSelection", "Yes"), ("row-other.scrollIntoView", "Yes") ] unexpected = [] for (k, ev) in expected: tr = driver.find_element_by_id(k) klass = tr.get_attribute("class") if "hasChild" in klass and "hidden" in klass: driver.execute_script("arguments[0].scrollIntoView()", tr) tr.click() v = tr.find_element_by_tag_name("td").text print(" {}: {}".format(k, v)) if not v.startswith(ev): unexpected.append((k, v, ev)) failed = False if score != expected_score: print("Unexpected score: {}/{} (expected {}/{})" .format(score[0], score[1], expected_score[0], expected_score[1]), file=sys.stderr) failed = True for k, v, ev in unexpected: print("Unexpected value for {}: {} (expected: {})".format(k, v, ev), file=sys.stderr) failed = True driver.quit() server.shutdown() server.server_close() server_thread.join() assert not failed