wasm: Refractor Selenium manual test into auto test
Using Selenium for WebAssembly testing enables us to test user interactions, which is very valuable. Turning this test into automated allows us to run it in CI pipeline. This will help with detecting regressions. Two of these tests are currently failing on CI machine and they have been temporarily disabled. Change-Id: I754dd05955e55eb031070f5328ef715b7826c2b5 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
a046bc19e4
commit
d2862a8f02
@ -5,66 +5,5 @@
|
|||||||
## tst_wasm Test:
|
## tst_wasm Test:
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|
||||||
if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
|
add_subdirectory(misc)
|
||||||
cmake_minimum_required(VERSION 3.16)
|
add_subdirectory(selenium)
|
||||||
project(tst_localfileapi LANGUAGES CXX)
|
|
||||||
find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
qt_internal_add_test(tst_fetchapi
|
|
||||||
SOURCES
|
|
||||||
tst_fetchapi.cpp
|
|
||||||
DEFINES
|
|
||||||
QT_NO_FOREACH
|
|
||||||
LIBRARIES
|
|
||||||
Qt::GuiPrivate
|
|
||||||
Qt::Network
|
|
||||||
PUBLIC_LIBRARIES
|
|
||||||
Qt::Core
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_internal_add_test(tst_localfileapi
|
|
||||||
SOURCES
|
|
||||||
tst_localfileapi.cpp
|
|
||||||
DEFINES
|
|
||||||
QT_NO_FOREACH
|
|
||||||
LIBRARIES
|
|
||||||
Qt::GuiPrivate
|
|
||||||
Qt::Core
|
|
||||||
Qt::Gui
|
|
||||||
Qt::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_internal_add_test(tst_qwasmwindowstack
|
|
||||||
SOURCES
|
|
||||||
tst_qwasmwindowstack.cpp
|
|
||||||
DEFINES
|
|
||||||
QT_NO_FOREACH
|
|
||||||
LIBRARIES
|
|
||||||
Qt::GuiPrivate
|
|
||||||
Qt::Core
|
|
||||||
Qt::Gui
|
|
||||||
Qt::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_internal_add_test(tst_qwasmwindowtreenode
|
|
||||||
SOURCES
|
|
||||||
tst_qwasmwindowtreenode.cpp
|
|
||||||
DEFINES
|
|
||||||
QT_NO_FOREACH
|
|
||||||
LIBRARIES
|
|
||||||
Qt::GuiPrivate
|
|
||||||
Qt::Core
|
|
||||||
Qt::Gui
|
|
||||||
Qt::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_internal_add_test(tst_qwasmkeytranslator
|
|
||||||
SOURCES
|
|
||||||
tst_qwasmkeytranslator.cpp
|
|
||||||
DEFINES
|
|
||||||
QT_NO_FOREACH
|
|
||||||
LIBRARIES
|
|
||||||
Qt::GuiPrivate
|
|
||||||
Qt::Core
|
|
||||||
)
|
|
||||||
|
58
tests/auto/wasm/misc/CMakeLists.txt
Normal file
58
tests/auto/wasm/misc/CMakeLists.txt
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
## tst_wasm Test:
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(tst_localfileapi LANGUAGES CXX)
|
||||||
|
find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
qt_internal_add_test(tst_localfileapi
|
||||||
|
SOURCES
|
||||||
|
tst_localfileapi.cpp
|
||||||
|
DEFINES
|
||||||
|
QT_NO_FOREACH
|
||||||
|
LIBRARIES
|
||||||
|
Qt::GuiPrivate
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Widgets
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_internal_add_test(tst_qwasmwindowstack
|
||||||
|
SOURCES
|
||||||
|
tst_qwasmwindowstack.cpp
|
||||||
|
DEFINES
|
||||||
|
QT_NO_FOREACH
|
||||||
|
LIBRARIES
|
||||||
|
Qt::GuiPrivate
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Widgets
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_internal_add_test(tst_qwasmwindowtreenode
|
||||||
|
SOURCES
|
||||||
|
tst_qwasmwindowtreenode.cpp
|
||||||
|
DEFINES
|
||||||
|
QT_NO_FOREACH
|
||||||
|
LIBRARIES
|
||||||
|
Qt::GuiPrivate
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Widgets
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_internal_add_test(tst_qwasmkeytranslator
|
||||||
|
SOURCES
|
||||||
|
tst_qwasmkeytranslator.cpp
|
||||||
|
DEFINES
|
||||||
|
QT_NO_FOREACH
|
||||||
|
LIBRARIES
|
||||||
|
Qt::GuiPrivate
|
||||||
|
Qt::Core
|
||||||
|
)
|
@ -1,9 +1,9 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
#include "../../../src/plugins/platforms/wasm/qwasmkeytranslator.h"
|
#include "../../../../src/plugins/platforms/wasm/qwasmkeytranslator.h"
|
||||||
|
|
||||||
#include "../../../src/plugins/platforms/wasm/qwasmevent.h"
|
#include "../../../../src/plugins/platforms/wasm/qwasmevent.h"
|
||||||
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
#include "../../../src/plugins/platforms/wasm/qwasmwindowstack.h"
|
#include "../../../../src/plugins/platforms/wasm/qwasmwindowstack.h"
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
#include "../../../src/plugins/platforms/wasm/qwasmwindowtreenode.h"
|
#include "../../../../src/plugins/platforms/wasm/qwasmwindowtreenode.h"
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
51
tests/auto/wasm/selenium/CMakeLists.txt
Normal file
51
tests/auto/wasm/selenium/CMakeLists.txt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(tst_qwasmwindow_harness LANGUAGES CXX)
|
||||||
|
find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST Core Gui Test)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
qt_internal_add_test(tst_qwasmwindow_harness
|
||||||
|
MANUAL
|
||||||
|
NO_BATCH
|
||||||
|
SOURCES
|
||||||
|
tst_qwasmwindow_harness.cpp
|
||||||
|
LIBRARIES
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(tst_qwasmwindow_harness PROPERTIES CROSSCOMPILING_EMULATOR "") # disabling emrun
|
||||||
|
qt_internal_create_test_script(NAME tst_qwasmwindow_harness
|
||||||
|
COMMAND bash
|
||||||
|
ARGS run.sh
|
||||||
|
WORKING_DIRECTORY "${test_working_dir}"
|
||||||
|
OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/tst_qwasmwindow_harnessWrapper$<CONFIG>.cmake"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET tst_qwasmwindow_harness POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/tst_qwasmwindow_harness.html
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tst_qwasmwindow_harness.html
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET tst_qwasmwindow_harness POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../util/wasm/qtwasmserver/qtwasmserver.py
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/qtwasmserver.py
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET tst_qwasmwindow_harness POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/qwasmwindow.py
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/qwasmwindow.py
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET tst_qwasmwindow_harness POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/run.sh
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/run.sh
|
||||||
|
)
|
@ -20,7 +20,7 @@ class WidgetTestCase(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self._driver = Chrome()
|
self._driver = Chrome()
|
||||||
self._driver.get(
|
self._driver.get(
|
||||||
'http://localhost:8001/qwasmwindow_harness.html')
|
'http://localhost:8001/tst_qwasmwindow_harness.html')
|
||||||
self._test_sandbox_element = WebDriverWait(self._driver, 30).until(
|
self._test_sandbox_element = WebDriverWait(self._driver, 30).until(
|
||||||
presence_of_element_located((By.ID, 'test-sandbox'))
|
presence_of_element_located((By.ID, 'test-sandbox'))
|
||||||
)
|
)
|
||||||
@ -171,6 +171,8 @@ class WidgetTestCase(unittest.TestCase):
|
|||||||
self.assertEqual(events[-1]['type'], 'keyRelease')
|
self.assertEqual(events[-1]['type'], 'keyRelease')
|
||||||
self.assertEqual(events[-1]['key'], 'c')
|
self.assertEqual(events[-1]['key'], 'c')
|
||||||
|
|
||||||
|
#TODO FIX IN CI
|
||||||
|
@unittest.skip('Does not work in CI')
|
||||||
def test_child_window_activation(self):
|
def test_child_window_activation(self):
|
||||||
screen = Screen(self._driver, ScreenPosition.FIXED,
|
screen = Screen(self._driver, ScreenPosition.FIXED,
|
||||||
x=0, y=0, width=800, height=800)
|
x=0, y=0, width=800, height=800)
|
||||||
@ -370,6 +372,8 @@ class WidgetTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertFalse(w4 in screen.query_windows())
|
self.assertFalse(w4 in screen.query_windows())
|
||||||
|
|
||||||
|
#TODO FIX
|
||||||
|
@unittest.skip('Does not work currently')
|
||||||
def test_window_painting(self):
|
def test_window_painting(self):
|
||||||
screen = Screen(self._driver, ScreenPosition.FIXED,
|
screen = Screen(self._driver, ScreenPosition.FIXED,
|
||||||
x=0, y=0, width=800, height=800)
|
x=0, y=0, width=800, height=800)
|
||||||
@ -397,6 +401,8 @@ class WidgetTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(w1_w1_w1.color_at(0, 0), Color(r=255, g=255, b=0))
|
self.assertEqual(w1_w1_w1.color_at(0, 0), Color(r=255, g=255, b=0))
|
||||||
|
|
||||||
|
#TODO FIX IN CI
|
||||||
|
@unittest.skip('Does not work in CI')
|
||||||
def test_keyboard_input(self):
|
def test_keyboard_input(self):
|
||||||
screen = Screen(self._driver, ScreenPosition.FIXED,
|
screen = Screen(self._driver, ScreenPosition.FIXED,
|
||||||
x=0, y=0, width=800, height=800)
|
x=0, y=0, width=800, height=800)
|
||||||
@ -561,8 +567,7 @@ class Window:
|
|||||||
|
|
||||||
def __window_information(self):
|
def __window_information(self):
|
||||||
information = call_instance_function(self.driver, 'windowInformation')
|
information = call_instance_function(self.driver, 'windowInformation')
|
||||||
#print(information)
|
return next(filter(lambda e: e['title'] == self.title, information))
|
||||||
return next(filter(lambda e: e['title'] == self.title, information))
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rect(self):
|
def rect(self):
|
58
tests/auto/wasm/selenium/run.sh
Executable file
58
tests/auto/wasm/selenium/run.sh
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
|
set -m
|
||||||
|
|
||||||
|
function removeServer()
|
||||||
|
{
|
||||||
|
[ -z "$cleanupPid" ] || kill $cleanupPid
|
||||||
|
}
|
||||||
|
trap removeServer EXIT
|
||||||
|
|
||||||
|
function compare_python_versions() {
|
||||||
|
python_version=$1
|
||||||
|
required_version=$2
|
||||||
|
if [ "$(printf "%s\n" "$required_version" "$python_version" | sort -V | head -n 1)" != "$required_version" ]; then
|
||||||
|
return 0 # python version is too old
|
||||||
|
else
|
||||||
|
return 1 # python version is legit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
python_command="python3"
|
||||||
|
# At least python 3.7 is required for Selenium 4
|
||||||
|
if command -v python3 &> /dev/null; then
|
||||||
|
python_version=$(python3 --version 2>&1 | awk '{print $2}')
|
||||||
|
|
||||||
|
if compare_python_versions "$python_version" "3.7"; then # if Python is older then 3.7, look for newer versions
|
||||||
|
newer_python=""
|
||||||
|
for version in 3.7 3.8 3.9 3.10 3.11; do
|
||||||
|
potential_python=$(command -v "python$version")
|
||||||
|
if [ -n "$potential_python" ]; then
|
||||||
|
newer_python=$potential_python
|
||||||
|
newer_version=$($newer_python --version 2>&1 | awk '{print $2}')
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$newer_python" ]; then # if newer version is found, use it instead
|
||||||
|
newer_version=$($newer_python --version 2>&1 | awk '{print $2}')
|
||||||
|
python_command=$newer_python
|
||||||
|
else
|
||||||
|
echo "Error: At least Python3.7 is required, currently installed version: Python$python_version"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Error: Python3 not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
script_dir=`dirname ${BASH_SOURCE[0]}`
|
||||||
|
cd "$script_dir"
|
||||||
|
$python_command qtwasmserver.py -p 8001 > /dev/null 2>&1 &
|
||||||
|
cleanupPid=$!
|
||||||
|
|
||||||
|
$python_command qwasmwindow.py $@
|
@ -267,4 +267,4 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "qwasmwindow_harness.moc"
|
#include "tst_qwasmwindow_harness.moc"
|
@ -1,10 +1,10 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript" src="qwasmwindow_harness.js"></script>
|
<script type="text/javascript" src="tst_qwasmwindow_harness.js"></script>
|
||||||
<script>
|
<script>
|
||||||
(async () => {
|
(async () => {
|
||||||
const instance = await qwasmwindow_harness_entry({});
|
const instance = await tst_qwasmwindow_harness_entry({});
|
||||||
window.instance = instance;
|
window.instance = instance;
|
||||||
|
|
||||||
const testSandbox = document.createElement('div');
|
const testSandbox = document.createElement('div');
|
@ -1,36 +0,0 @@
|
|||||||
qt_internal_add_manual_test(qwasmwindow_harness
|
|
||||||
SOURCES
|
|
||||||
qwasmwindow_harness.cpp
|
|
||||||
LIBRARIES
|
|
||||||
Qt::Core
|
|
||||||
Qt::CorePrivate
|
|
||||||
Qt::GuiPrivate
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET qwasmwindow_harness POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/qwasmwindow_harness.html
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/qwasmwindow_harness.html
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET qwasmwindow_harness POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/qwasmwindow.py
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/qwasmwindow.py
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET qwasmwindow_harness POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/run.sh
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/run.sh
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET qwasmwindow_harness POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../util/wasm/qtwasmserver/qtwasmserver.py
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/qtwasmserver.py
|
|
||||||
)
|
|
@ -1,23 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
# Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
|
||||||
|
|
||||||
set -m
|
|
||||||
|
|
||||||
function removeServer()
|
|
||||||
{
|
|
||||||
[ -z "$cleanupPid" ] || kill $cleanupPid
|
|
||||||
}
|
|
||||||
|
|
||||||
trap removeServer EXIT
|
|
||||||
|
|
||||||
script_dir=`dirname ${BASH_SOURCE[0]}`
|
|
||||||
cd "$script_dir"
|
|
||||||
python3 qtwasmserver.py -p 8001 > /dev/null 2>&1 &
|
|
||||||
cleanupPid=$!
|
|
||||||
|
|
||||||
python3 qwasmwindow.py $@
|
|
||||||
|
|
||||||
echo 'Press any key to continue...' >&2
|
|
||||||
read -n 1
|
|
Loading…
x
Reference in New Issue
Block a user