Add login appium test
This commit is contained in:
@@ -58,5 +58,9 @@ Dependencies:
|
|||||||
'require':
|
'require':
|
||||||
'frameworks/kdbusaddons': '@latest-kf6'
|
'frameworks/kdbusaddons': '@latest-kf6'
|
||||||
|
|
||||||
|
- 'on': ['Linux/Qt6', 'Linux/Qt5']
|
||||||
|
'require':
|
||||||
|
'sdk/selenium-webdriver-at-spi': '@latest-kf6'
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD', 'Windows' ]
|
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD', 'Windows' ]
|
||||||
|
|||||||
@@ -176,8 +176,11 @@ add_definitions(-DQT_NO_FOREACH)
|
|||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
if (BUILD_TESTING)
|
||||||
add_subdirectory(autotests)
|
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||||
|
add_subdirectory(autotests)
|
||||||
|
add_subdirectory(appiumtests)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(KF${QT_MAJOR_VERSION}DocTools_FOUND)
|
if(KF${QT_MAJOR_VERSION}DocTools_FOUND)
|
||||||
kdoctools_install(po)
|
kdoctools_install(po)
|
||||||
|
|||||||
23
appiumtests/CMakeLists.txt
Normal file
23
appiumtests/CMakeLists.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
# SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
|
||||||
|
|
||||||
|
|
||||||
|
if(NOT BUILD_TESTING OR NOT CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(SeleniumWebDriverATSPI)
|
||||||
|
set_package_properties(SeleniumWebDriverATSPI PROPERTIES
|
||||||
|
DESCRIPTION "Server component for selenium tests using Linux accessibility infrastructure"
|
||||||
|
PURPOSE "Needed for GUI tests"
|
||||||
|
URL "https://invent.kde.org/sdk/selenium-webdriver-at-spi"
|
||||||
|
TYPE OPTIONAL
|
||||||
|
)
|
||||||
|
if(NOT SeleniumWebDriverATSPI_FOUND)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME logintest
|
||||||
|
COMMAND selenium-webdriver-at-spi-run ${CMAKE_CURRENT_SOURCE_DIR}/logintest.py
|
||||||
|
)
|
||||||
42
appiumtests/login-server.py
Normal file
42
appiumtests/login-server.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
|
||||||
|
|
||||||
|
from flask import Flask, request, abort
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route("/_matrix/client/v3/login", methods=["GET"])
|
||||||
|
def login_get():
|
||||||
|
result = dict()
|
||||||
|
result["flows"] = [dict()]
|
||||||
|
result["flows"][0]["type"] = "m.login.password"
|
||||||
|
return result
|
||||||
|
|
||||||
|
@app.route("/_matrix/client/v3/login", methods=["POST"])
|
||||||
|
def login_post():
|
||||||
|
data = request.get_json()
|
||||||
|
if data["identifier"]["user"] != "user" or data["password"] != "1234":
|
||||||
|
abort(403)
|
||||||
|
print(data)
|
||||||
|
result = dict()
|
||||||
|
result["access_token"] = "token_1234"
|
||||||
|
result["device_id"] = "device_1234"
|
||||||
|
result["user_id"] = "@user:localhost:1234"
|
||||||
|
return result
|
||||||
|
|
||||||
|
@app.route("/_matrix/client/r0/sync")
|
||||||
|
def sync():
|
||||||
|
result = dict()
|
||||||
|
result["next_batch"] = "batch1234"
|
||||||
|
return result
|
||||||
|
|
||||||
|
@app.route("/.well-known/matrix/client")
|
||||||
|
def well_known():
|
||||||
|
reply = dict()
|
||||||
|
reply["m.homeserver"] = dict()
|
||||||
|
reply["m.homeserver"]["base_url"] = "https://localhost:1234"
|
||||||
|
return reply
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(ssl_context='adhoc', port=1234)
|
||||||
44
appiumtests/logintest.py
Executable file
44
appiumtests/logintest.py
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
# SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org>
|
||||||
|
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from appium import webdriver
|
||||||
|
from appium.webdriver.common.appiumby import AppiumBy
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
class LoginTest(unittest.TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(self):
|
||||||
|
desired_caps = {}
|
||||||
|
desired_caps["app"] = "neochat --ignore-ssl-errors"
|
||||||
|
desired_caps["timeouts"] = {'implicit': 10000}
|
||||||
|
self.driver = webdriver.Remote(
|
||||||
|
command_executor='http://127.0.0.1:4723',
|
||||||
|
desired_capabilities=desired_caps)
|
||||||
|
subprocess.Popen(["python","login-server.py"])
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
if not self._outcome.result.wasSuccessful():
|
||||||
|
self.driver.get_screenshot_as_file("failed_test_shot_{}.png".format(self.id()))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(self):
|
||||||
|
self.driver.quit()
|
||||||
|
|
||||||
|
def test_login(self):
|
||||||
|
self.driver.find_element(by=AppiumBy.NAME, value="Matrix ID").send_keys("@user:localhost:1234")
|
||||||
|
self.driver.find_element(by=AppiumBy.NAME, value="Continue").click()
|
||||||
|
self.driver.find_element(by=AppiumBy.NAME, value="Password").send_keys("1234")
|
||||||
|
self.driver.find_element(by=AppiumBy.NAME, value="Login").click()
|
||||||
|
self.driver.find_element(by=AppiumBy.NAME, value="Join some rooms to get started").click()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QNetworkProxyFactory>
|
#include <QNetworkProxyFactory>
|
||||||
|
#include <QObject>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QQmlNetworkAccessManagerFactory>
|
#include <QQmlNetworkAccessManagerFactory>
|
||||||
@@ -323,11 +324,18 @@ int main(int argc, char *argv[])
|
|||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription(i18n("Client for the matrix communication protocol"));
|
parser.setApplicationDescription(i18n("Client for the matrix communication protocol"));
|
||||||
parser.addPositionalArgument(QStringLiteral("urls"), i18n("Supports matrix: url scheme"));
|
parser.addPositionalArgument(QStringLiteral("urls"), i18n("Supports matrix: url scheme"));
|
||||||
|
parser.addOption(QCommandLineOption("ignore-ssl-errors", i18n("Ignore all SSL Errors, e.g., unsigned certificates.")));
|
||||||
|
|
||||||
about.setupCommandLine(&parser);
|
about.setupCommandLine(&parser);
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
about.processCommandLine(&parser);
|
about.processCommandLine(&parser);
|
||||||
|
|
||||||
|
if (parser.isSet("ignore-ssl-errors")) {
|
||||||
|
QObject::connect(NetworkAccessManager::instance(), &QNetworkAccessManager::sslErrors, NetworkAccessManager::instance(), [](QNetworkReply *reply) {
|
||||||
|
reply->ignoreSslErrors();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
engine.addImageProvider(QLatin1String("mxc"), new MatrixImageProvider);
|
engine.addImageProvider(QLatin1String("mxc"), new MatrixImageProvider);
|
||||||
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
|
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ LoginStep {
|
|||||||
id: matrixIdField
|
id: matrixIdField
|
||||||
Kirigami.FormData.label: i18n("Matrix ID:")
|
Kirigami.FormData.label: i18n("Matrix ID:")
|
||||||
placeholderText: "@user:matrix.org"
|
placeholderText: "@user:matrix.org"
|
||||||
|
Accessible.name: i18n("Matrix ID")
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
LoginHelper.matrixId = text
|
LoginHelper.matrixId = text
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ LoginStep {
|
|||||||
id: passwordField
|
id: passwordField
|
||||||
onTextChanged: LoginHelper.password = text
|
onTextChanged: LoginHelper.password = text
|
||||||
enabled: !LoginHelper.isLoggingIn
|
enabled: !LoginHelper.isLoggingIn
|
||||||
|
Accessible.name: i18n("Password")
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
passwordField.forceActiveFocus()
|
passwordField.forceActiveFocus()
|
||||||
|
|||||||
Reference in New Issue
Block a user