From b4ef0031c67a99ebd98fb324eff8ad2ce5af025d Mon Sep 17 00:00:00 2001 From: Mikolaj Boc Date: Wed, 2 Nov 2022 15:48:44 +0100 Subject: [PATCH] Set up a manual test for qt loader Skeleton tests included. Run the test with run.sh. Fixes: QTBUG-107744 Change-Id: Ic2734e24025f8edc0f8e710d981367aa321f9066 Reviewed-by: Edward Welbourne --- tests/manual/wasm/qtloader/tst_qtloader.html | 19 +++++ tests/manual/wasm/qtloader/tst_qtloader.js | 42 +++++++++++ tests/manual/wasm/shared/.gitignore | 1 + tests/manual/wasm/shared/run.sh | 30 ++++++++ tests/manual/wasm/shared/testrunner.js | 78 ++++++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 tests/manual/wasm/qtloader/tst_qtloader.html create mode 100644 tests/manual/wasm/qtloader/tst_qtloader.js create mode 100644 tests/manual/wasm/shared/.gitignore create mode 100755 tests/manual/wasm/shared/run.sh create mode 100644 tests/manual/wasm/shared/testrunner.js diff --git a/tests/manual/wasm/qtloader/tst_qtloader.html b/tests/manual/wasm/qtloader/tst_qtloader.html new file mode 100644 index 00000000000..c85bccc68d0 --- /dev/null +++ b/tests/manual/wasm/qtloader/tst_qtloader.html @@ -0,0 +1,19 @@ + + + + + + + + Qt Loader tests + + + + + + diff --git a/tests/manual/wasm/qtloader/tst_qtloader.js b/tests/manual/wasm/qtloader/tst_qtloader.js new file mode 100644 index 00000000000..39e0d128075 --- /dev/null +++ b/tests/manual/wasm/qtloader/tst_qtloader.js @@ -0,0 +1,42 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import { TestRunner } from '../shared/testrunner.js'; + +class QtLoaderTests +{ + async beforeEach() { sinon.stub(window, 'alert'); } + + async afterEach() { sinon.restore(); } + + async sampleTestCase() + { + await new Promise(resolve => + { + window.alert(); + sinon.assert.calledOnce(window.alert); + window.setTimeout(resolve, 4000); + }); + } + + async sampleTestCase2() + { + await new Promise(resolve => + { + window.alert(); + sinon.assert.calledOnce(window.alert); + window.setTimeout(resolve, 1000); + }); + } + + async constructQtLoader() + { + new QtLoader({}); + } +} + +(async () => +{ + const runner = new TestRunner(new QtLoaderTests()); + await runner.runAll(); +})(); diff --git a/tests/manual/wasm/shared/.gitignore b/tests/manual/wasm/shared/.gitignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/tests/manual/wasm/shared/.gitignore @@ -0,0 +1 @@ +bin diff --git a/tests/manual/wasm/shared/run.sh b/tests/manual/wasm/shared/run.sh new file mode 100755 index 00000000000..d8ae18919c4 --- /dev/null +++ b/tests/manual/wasm/shared/run.sh @@ -0,0 +1,30 @@ +#! /bin/bash + +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +set -m + +function removeServer() +{ + kill $cleanupPid +} + +if [ -z "$1"] +then + echo "Usage: $0 testname, where testname is a test in the tests/manual/wasm directory" >&2 + exit 1 +fi + +trap removeServer EXIT + +script_dir=`dirname ${BASH_SOURCE[0]}` +cd "$script_dir/../../../../" +python3 -m http.server 8001 & +cleanupPid=$! +cd - + +python3 -m webbrowser "http://localhost:8001/tests/manual/wasm/$1/tst_$1.html" + +echo 'Press any key to continue...' >&2 +read -n 1 diff --git a/tests/manual/wasm/shared/testrunner.js b/tests/manual/wasm/shared/testrunner.js new file mode 100644 index 00000000000..da87026b03c --- /dev/null +++ b/tests/manual/wasm/shared/testrunner.js @@ -0,0 +1,78 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +function output(message) +{ + const outputLine = document.createElement('div'); + outputLine.style.fontFamily = 'monospace'; + outputLine.innerText = message; + + document.body.appendChild(outputLine); + + console.log(message); +} + +export class TestRunner +{ + #testClassInstance + + constructor(testClassInstance) + { + this.#testClassInstance = testClassInstance; + } + + async run(testCase) + { + const prototype = Object.getPrototypeOf(this.#testClassInstance); + try { + output(`Running ${testCase}`); + if (!prototype.hasOwnProperty(testCase)) + throw new Error(`No such testcase ${testCase}`); + + if (prototype.beforeEach) { + await prototype.beforeEach.apply(this.#testClassInstance); + } + + await new Promise((resolve, reject) => + { + let rejected = false; + const timeout = window.setTimeout(() => + { + rejected = true; + reject(new Error('Timeout after 2 seconds')); + }, 2000); + prototype[testCase].apply(this.#testClassInstance).then(() => + { + if (!rejected) { + window.clearTimeout(timeout); + output(`✅ Test passed ${testCase}`); + resolve(); + } + }).catch(reject); + }); + } catch (e) { + output(`❌ Failed ${testCase}: exception ${e} ${e.stack}`); + } finally { + if (prototype.afterEach) { + await prototype.afterEach.apply(this.#testClassInstance); + } + } + } + + async runAll() + { + const SPECIAL_FUNCTIONS = + ['beforeEach', 'afterEach', 'beforeAll', 'afterAll', 'constructor']; + const prototype = Object.getPrototypeOf(this.#testClassInstance); + const testFunctions = + Object.getOwnPropertyNames(prototype).filter( + entry => SPECIAL_FUNCTIONS.indexOf(entry) === -1); + + if (prototype.beforeAll) + await prototype.beforeAll.apply(this.#testClassInstance); + for (const fn of testFunctions) + await this.run(fn); + if (prototype.afterAll) + await prototype.afterAll.apply(this.#testClassInstance); + } +}