aboutsummaryrefslogtreecommitdiffstats
path: root/squishtests
diff options
context:
space:
mode:
authorSven Kroemeke <skroemeke@luxoft.com>2018-09-26 16:51:36 +0200
committerBramastyo Harimukti Santoso <bramastyo.harimukti.santoso@pelagicore.com>2018-10-09 13:24:44 +0000
commit582192d7101e6f9fe4aa1b5a0a1a6d8022a3b731 (patch)
tree2c77aa6add747888d1293cbc691cf7f8794218b3 /squishtests
parentc91049909df6bd7742bfdc2c84dc701fe56e663a (diff)
[squish] Initial commit for basic structure of squish test suite
Change-Id: Iba68cc0f7e57ab5816ee712fbaaae7b79e4154c1 Reviewed-by: Bramastyo Harimukti Santoso <bramastyo.harimukti.santoso@pelagicore.com>
Diffstat (limited to 'squishtests')
-rw-r--r--squishtests/suite_neptune3/config.xml9
-rw-r--r--squishtests/suite_neptune3/extension/NeptuneWidgets.qml51
-rw-r--r--squishtests/suite_neptune3/shared/objects.map9
-rw-r--r--squishtests/suite_neptune3/shared/objects.map.local16
-rw-r--r--squishtests/suite_neptune3/shared/scripts/bdd_hooks.py219
-rwxr-xr-xsquishtests/suite_neptune3/shared/scripts/generate_sqlite.py169
-rw-r--r--squishtests/suite_neptune3/shared/scripts/names.py70
-rw-r--r--squishtests/suite_neptune3/shared/steps/essential.py130
-rw-r--r--squishtests/suite_neptune3/shared/steps/steps.py74
-rw-r--r--squishtests/suite_neptune3/suite.conf11
10 files changed, 758 insertions, 0 deletions
diff --git a/squishtests/suite_neptune3/config.xml b/squishtests/suite_neptune3/config.xml
new file mode 100644
index 00000000..d043f645
--- /dev/null
+++ b/squishtests/suite_neptune3/config.xml
@@ -0,0 +1,9 @@
+<testconfig version="1.0">
+<information>
+<summary/>
+<description/>
+</information>
+<testsettings>
+<waitForObjectTimeout>200000</waitForObjectTimeout>
+</testsettings>
+</testconfig>
diff --git a/squishtests/suite_neptune3/extension/NeptuneWidgets.qml b/squishtests/suite_neptune3/extension/NeptuneWidgets.qml
new file mode 100644
index 00000000..c2d173e3
--- /dev/null
+++ b/squishtests/suite_neptune3/extension/NeptuneWidgets.qml
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Luxoft GmbH
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune 3 IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+import QtQuick 2.0
+import com.froglogic.squish.qtquick 0.1
+
+
+// copy this file to ~SQUISHDIR/lib/extensions/qt/qtquick
+SquishHook {
+ priority: 120
+ function isIgnored( item ) {
+ if ( item.parent && qmlType( item.parent ) == "ClimateBar" ) {
+ return true;
+ }
+ return unhandled;
+ }
+
+ function extraPropertiesFor( item ) {
+ if ( qmlType( item ) == 'ClimateBar' ) {
+ return [ 'mtext' ];
+ }
+ return unhandled;
+ }
+}
diff --git a/squishtests/suite_neptune3/shared/objects.map b/squishtests/suite_neptune3/shared/objects.map
new file mode 100644
index 00000000..84cbc52f
--- /dev/null
+++ b/squishtests/suite_neptune3/shared/objects.map
@@ -0,0 +1,9 @@
+:Neptune UI - Center Console.grid_GridView {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='grid' type='GridView' unnamed='1' visible='true'}
+:Neptune UI - Center Console.instrumentClusterWindowLoader_Loader {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='instrumentClusterWindowLoader' type='Loader' unnamed='1' visible='true'}
+:Neptune UI - Center Console.leftIcon_ToolButton {checkable='false' container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='leftIcon' type='ToolButton' unnamed='1' visible='true'}
+:Neptune UI - Center Console.leftTempSlider_TemperatureSlider {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='leftTempSlider' type='TemperatureSlider' unnamed='1' visible='true'}
+:Neptune UI - Center Console.rightTempSlider_TemperatureSlider {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='rightTempSlider' type='TemperatureSlider' unnamed='1' visible='true'}
+:Neptune UI - Center Console.root_ClimatePopup {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='root' type='ClimatePopup' unnamed='1' visible='true'}
+:Neptune UI - Center Console_QQuickWindowQmlImpl {title='Neptune UI - Center Console' type='QQuickWindowQmlImpl' unnamed='1' visible='true'}
+:Neptune UI - Instrument Cluster_QQuickWindowQmlImpl {title='Neptune UI - Instrument Cluster' type='QQuickWindowQmlImpl' unnamed='1' visible='true' window=':_QVariant'}
+:_QVariant {type='QVariant'}
diff --git a/squishtests/suite_neptune3/shared/objects.map.local b/squishtests/suite_neptune3/shared/objects.map.local
new file mode 100644
index 00000000..292a9bb7
--- /dev/null
+++ b/squishtests/suite_neptune3/shared/objects.map.local
@@ -0,0 +1,16 @@
+:Neptune UI - Center Console.borderImage_BorderImage {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='borderImage' source='$BINPATH_TEST/imports/assets/gfx/popup-background-9patch.png' type='BorderImage' unnamed='1' visible='true'}
+:Neptune UI - Center Console.grid_GridView {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='grid' type='GridView' unnamed='1' visible='true'}
+:Neptune UI - Center Console.handle_Image {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='handle' source='$BINPATH_TEST/imports/assets/gfx/slider-handle-vertical.png' type='Image' unnamed='1' visible='true'}
+:Neptune UI - Center Console.image_IconImage {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' objectName='image' source='$BINPATH_TEST/imports/assets/icons/neptune/sysui/ic-volume-1.png' type='IconImage' visible='true'}
+:Neptune UI - Center Console.image_IconImage_2 {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' objectName='image' source='$BINPATH_TEST/imports/assets/icons/neptune/sysui/ic-close.png' type='IconImage' visible='true'}
+:Neptune UI - Center Console.image_IconImage_3 {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' objectName='image' source='$BINPATH_TEST/imports/assets/icons/neptune/sysui/ic-menu-allapps.png' type='IconImage' visible='true'}
+:Neptune UI - Center Console.instrumentClusterWindowLoader_Loader {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='instrumentClusterWindowLoader' type='Loader' unnamed='1' visible='true'}
+:Neptune UI - Center Console.leftIcon_ToolButton {checkable='false' container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='leftIcon' type='ToolButton' unnamed='1' visible='true'}
+:Neptune UI - Center Console.leftTempSlider_TemperatureSlider {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='leftTempSlider' type='TemperatureSlider' unnamed='1' visible='true'}
+:Neptune UI - Center Console.rightTempSlider_TemperatureSlider {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='rightTempSlider' type='TemperatureSlider' unnamed='1' visible='true'}
+:Neptune UI - Center Console.root_ClimatePopup {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' id='root' type='ClimatePopup' unnamed='1' visible='true'}
+:Neptune UI - Center Console_Image {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' source='$BINPATH_TEST/imports/assets/icons/ic-rear-defrost-status.png' type='Image' unnamed='1' visible='true'}
+:Neptune UI - Center Console_Image_2 {container=':Neptune UI - Center Console_QQuickWindowQmlImpl' source='$BINPATH_TEST/imports/assets/gfx/bg-home.png' type='Image' unnamed='1' visible='true'}
+:Neptune UI - Center Console_QQuickWindowQmlImpl {title='Neptune UI - Center Console' type='QQuickWindowQmlImpl' unnamed='1' visible='true'}
+:Neptune UI - Instrument Cluster_QQuickWindowQmlImpl {title='Neptune UI - Instrument Cluster' type='QQuickWindowQmlImpl' unnamed='1' visible='true' window=':_QVariant'}
+:_QVariant {type='QVariant'}
diff --git a/squishtests/suite_neptune3/shared/scripts/bdd_hooks.py b/squishtests/suite_neptune3/shared/scripts/bdd_hooks.py
new file mode 100644
index 00000000..bb2175b3
--- /dev/null
+++ b/squishtests/suite_neptune3/shared/scripts/bdd_hooks.py
@@ -0,0 +1,219 @@
+# -*- coding: utf-8 -*-
+
+############################################################################
+##
+## Copyright (C) 2018 Luxoft GmbH
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Neptune 3 IVI UI.
+##
+## $QT_BEGIN_LICENSE:GPL-QTAS$
+## Commercial License Usage
+## Licensees holding valid commercial Qt Automotive Suite licenses may use
+## this file in accordance with the commercial license agreement provided
+## with the Software or, alternatively, in accordance with the terms
+## contained in a written agreement between you and The Qt Company. For
+## licensing terms and conditions see https://www.qt.io/terms-conditions.
+## For further information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+## SPDX-License-Identifier: GPL-3.0
+##
+#############################################################################
+
+
+# This file contains hook functions to run as the .feature file is executed.
+#
+# A common use-case is to use the OnScenarioStart/OnScenarioEnd hooks to
+# start and stop an AUT, e.g.
+#
+# @OnScenarioStart
+# def hook(context):
+# startApplication("addressbook")
+#
+# @OnScenarioEnd
+# def hook(context):
+# currentApplicationContext().detach()
+#
+# See the section 'Performing Actions During Test Execution Via Hooks' in the Squish
+# manual for a complete reference of the available API.
+
+import names
+
+# waiting time to let all windows to arrange at start-up
+STARTUP_ARRANGE_TIME_SEC = 1
+STARTUP_RETRIES = 0
+STARTUP_RETRIES_WAIT_SEC = 2
+END_DEARRANGE_TIME_SEC = 3
+
+
+@OnFeatureEnd
+def hook(context):
+ for ctx in applicationContextList():
+ ctx.detach()
+ snooze(END_DEARRANGE_TIME_SEC)
+
+
+# unfortunately not readable by the AUT given in the project's test config of squish, those variable are not usable within the test
+AUT="neptune3-ui"
+
+# clean up a little more
+def start_neptune_ui_app_w_focus(window):
+ def repeater(tries):
+ global SCREEN_HEIGHT
+ global SCREEN_WIDTH
+ global SCREEN_LANDSCAPE
+
+ try:
+ appman = {"type":"QtAM::ApplicationManagerWindow"}
+ #obj = waitForObject(appman,1000)
+ except Exception as e:
+ test.fail("Appman not found!!:" + str(e))
+ else:
+ #command_line_options = "--start-session-dbus --r"
+
+ #command_line_options = "--start-session-dbus -platform eglfs -plugin evdevkeyboard:grab=1"
+
+ #command_line_options = "-r -c am-config.yaml --start-session-dbus -platform eglfs -plugin evdevkeyboard:grab=1 --logging-rule \"*=true\" --logging-rule \"Qt3D.*.debug=false\" --logging-rule=\"qt.*.debug=false\""
+ command_line_options = "-r --start-session-dbus"
+
+ command_line = AUT + " " + command_line_options
+ try:
+ startApplication(command_line)
+ # wait for windows to arrange
+ test.log("Start up application with: '" + command_line + "'!")
+ snooze(STARTUP_ARRANGE_TIME_SEC)
+
+ worked, window_obj = get_focus_window(window)
+ if not worked:
+ return False
+ except Exception as e:
+ if tries > 0:
+ test.log("retrying to start AUT '" + AUT + "'!")
+ snooze(STARTUP_RETRIES_WAIT_SEC)
+ return repeater(tries-1)
+ else:
+ test.fail("Window not found after " + str(STARTUP_RETRIES) + " retries!!:" + str(e))
+ return False
+ else:
+ # only for console so far
+
+ test.log("Window size is : " + str(window_obj.width) + "," + str(window_obj.height))
+ test.log("Window pos is : " + str(window_obj.x) + "," + str(window_obj.y))
+ try:
+ console_inside = waitForObject(names.neptune_3_UI_Center_Console_centerConsole_CenterConsole,500)
+ except Exception:
+ pass
+ else:
+ test.log("----------------------")
+ SCREEN_WIDTH = console_inside.width
+ SCREEN_HEIGHT = console_inside.height
+ SCREEN_LANDSCAPE = True
+ test.log("Console size : " + str(SCREEN_WIDTH) + "," + str(SCREEN_HEIGHT))
+ test.log("Console offset is: " + str(console_inside.x) + "," + str(console_inside.y))
+
+
+ # from https://kb.froglogic.com/display/KB/Problem+-+Bringing+window+to+foreground+%28Qt%29
+ window_obj.show()
+ getattr(window_obj, "raise")()
+ #not needed any more??? o.activateWindow()
+ return True
+ # run here
+ repeater(STARTUP_RETRIES)
+
+def get_focus_window(window):
+ found = True
+ if window == "dashboard":
+ obj_name = names.neptune_UI_Instrument_Cluster_QQuickWindowQmlImpl
+ elif window == "console":
+ obj_name = names.neptune_UI_Center_Console
+ else:
+ test.fail("The given window '" + window + "' is not known!!")
+ obj = None
+ found = False
+ return found, obj
+ try:
+ obj = waitForObject(obj_name,1000)
+ except Exception as e:
+ test.fail("Could not find window '" + window + "'!!" + str(e))
+ obj = None
+ found = False
+
+ return found, obj
+
+
+# pos = QCursor.pos()
+# test.log("Local Position is: " + str(pos.x) + "/" + str(pos.y))
+
+
+def get_middle_of_object(obj):
+ try:
+ posx = obj.x
+ posy = obj.y
+ except Exception as e:
+ test.fail("Fail due to: " + str(e))
+ return False, QPoint(0,0)
+ else:
+ return True, QPoint(posx,posy)
+
+def get_info(obj):
+ try:
+ posx = obj.x
+ posy = obj.y
+ width = obj.width
+ height = obj.height
+ except Exception as e:
+ test.fail("Fail due to: " + str(e))
+ else:
+ test.log("(" + str(posx) + "," + str(posy) + ") size [" + str(width) + "," + str(height) + "]")
+
+
+
+#helper
+def get_midth_of_item(itemObjectOrName):
+ item = waitForObject(itemObjectOrName)
+ if className(item) != "QQuickItem":
+ try:
+ item = object.convertTo(item, "QQuickItem")
+ except Exception as e:
+ test.log("Positioning object could not be converted to QQuickItem: " + str(e))
+ return False, QPoint(0,0)
+ return True, QPoint(item.x + math.floor(item.width/2),item.y + math.floor(item.height/2))
+
+
+def get_position_item(itemObjectOrName):
+ def recursive_go_deep(obj):
+ parent = object.parent(obj)
+ if parent:
+ worked, rel_pos = recursive_go_deep(parent)
+ if worked:
+ posx = obj.x + rel_pos.x
+ posy = obj.y + rel_pos.y
+ return True, QPoint(posx,posy)
+ else:
+ return False, QPoint(0,0)
+ else:
+ return True, QPoint(obj.x,obj.y)
+
+ item = waitForObject(itemObjectOrName)
+ if className(item) != "QQuickItem":
+ try:
+ item = object.convertTo(item, "QQuickItem")
+ except Exception as e:
+ test.log("Positioning object could not be converted to QQuickItem: " + str(e))
+ return False, QPoint(0,0)
+ worked, pos = recursive_go_deep(item)
+ return worked, pos
+
+
+# from https://kb.froglogic.com/display/KB/Getting+screen+coordinates+of+QGraphicsItem%2C+QGraphicsObject
diff --git a/squishtests/suite_neptune3/shared/scripts/generate_sqlite.py b/squishtests/suite_neptune3/shared/scripts/generate_sqlite.py
new file mode 100755
index 00000000..12ee6806
--- /dev/null
+++ b/squishtests/suite_neptune3/shared/scripts/generate_sqlite.py
@@ -0,0 +1,169 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+############################################################################
+##
+## Copyright (C) 2018 Luxoft GmbH
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Neptune 3 IVI UI.
+##
+## $QT_BEGIN_LICENSE:GPL-QTAS$
+## Commercial License Usage
+## Licensees holding valid commercial Qt Automotive Suite licenses may use
+## this file in accordance with the commercial license agreement provided
+## with the Software or, alternatively, in accordance with the terms
+## contained in a written agreement between you and The Qt Company. For
+## licensing terms and conditions see https://www.qt.io/terms-conditions.
+## For further information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+## SPDX-License-Identifier: GPL-3.0
+##
+#############################################################################
+
+# please call this program directly and not via "python ./generate_sqlite.py"
+
+# This program reads media files from a directory (via taglib library)
+# and stores few items in a sqlite3 database.
+
+# table name: SONG with TITLE, ARTIST, ALBUM yet
+
+# coding guidelines I will try to follow https://www.python.org/dev/peps/pep-0008/
+
+# packages needed:
+# pip install --user pytaglib https://github.com/supermihi/pytaglib
+# pip install --user python-magic https://github.com/ahupp/python-magic
+# pip install --user result https://pypi.org/project/result/ MIT
+
+import taglib # for idtags
+import os # directory/file/path access
+import sys # args
+import sqlite3 # db connect
+import hashlib # duplicates recognition via hash
+import magic # for mime/type identification
+import result # a rust like result
+
+from result import Ok, Err
+
+# try to insert song into the db
+def insert_into_db(connection, songtag, result_image):
+ # tags are mostly a list!!
+ titles = songtag.tags["TITLE"]
+ artists = songtag.tags["ARTIST"]
+ albums = songtag.tags["ALBUM"]
+
+ # take first item and take "unknown" if empty
+ title = titles[0] if titles else "unknown"
+ artist = artists[0] if artists else "unknown"
+ album = albums[0] if albums else "unknown"
+ # image string if not there is empty
+ image = result_image.value if Ok(result_image) else ""
+
+ # to ensure uniqueness we add the hash of the strings together (not image)
+ hash_prep = title + "_" + artist + "_" + album
+ hash_for_unique_key = hashlib.md5(hash_prep.encode('utf-8')).hexdigest()
+
+ try:
+ # this form should be stable with utf8 and escaping
+ connection.execute('INSERT OR IGNORE INTO SONGS VALUES (?,?,?,?,?)'
+ ,(title,artist,album,image, hash_for_unique_key))
+ except sqlite3.DatabaseError as e:
+ # duplicates maybe
+ pass
+ except Exception as e:
+ print("title: %s" %title)
+ print("artist: %s" %artist)
+ print("album: %s" %album)
+ print(e)
+ pass
+ else:
+ return Ok(())
+ return Err('File could not added')
+
+# find image file partnering the given file
+def find_image(file):
+ # prepare mime
+ mime = magic.Magic(mime=True)
+ # decompose dir,name and extension
+ dir = os.path.dirname(file)
+ base = os.path.basename(file)
+ name,extension = os.path.splitext(base)
+
+ for f_name in os.listdir(dir):
+ if f_name.startswith(name):
+ candidate = os.path.join(dir,f_name)
+ # mime split not path!!!
+ candidate_mime_main = mime.from_file(candidate).split("/")[0]
+ if candidate_mime_main == 'image':
+ # first image file found is already enough
+ return Ok(candidate)
+ return Err('no image could be found!')
+
+
+# ################################################################
+
+
+# Set the directory you want to start from
+arg_len = len(sys.argv)
+if len(sys.argv) != 3:
+ print("exactly 2 parameter (start directory) (path and name to db) allowed")
+ quit()
+else:
+ source_dir = sys.argv[1]
+ target_name = sys.argv[2]
+
+
+conn = sqlite3.connect(target_name)
+try:
+ conn.execute(
+ '''CREATE TABLE SONGS (TITLE text, ARTIST text, ALBUM text, image text, hash text, PRIMARY key(hash))'''
+ )
+except sqlite3.DatabaseError as e:
+ print("Probably already existing database")
+ #print(e)
+except Exception as e:
+ print(e)
+ quit()
+
+good_songs = 0
+bad_songs = 0
+no_song = 0
+images_song = 0
+
+for dir_name, subdirList, fileList in os.walk(source_dir):
+ #print('Found directory: %s' % dirName)
+ for fname in fileList:
+ full_name = os.path.join(dir_name,fname)
+ stats = (good_songs,bad_songs)
+ try:
+ song = taglib.File(full_name)
+ except Exception:
+ no_song+=1
+ # these files could not be read by taglib
+ pass
+ else:
+ result_image = find_image(full_name)
+ if result_image.is_ok():
+ images_song+=1
+ if insert_into_db(conn,song,result_image).is_ok():
+ good_songs+=1
+ else:
+ bad_songs+=1
+
+# commit changes to database
+conn.commit()
+# don't forget to close
+conn.close()
+print("Found %s valid songs (%s accompanying images, %s not processible), and %s other files."
+ %(good_songs,images_song, bad_songs,no_song))
diff --git a/squishtests/suite_neptune3/shared/scripts/names.py b/squishtests/suite_neptune3/shared/scripts/names.py
new file mode 100644
index 00000000..d3a7dc22
--- /dev/null
+++ b/squishtests/suite_neptune3/shared/scripts/names.py
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+
+############################################################################
+##
+## Copyright (C) 2018 Luxoft GmbH
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Neptune 3 IVI UI.
+##
+## $QT_BEGIN_LICENSE:GPL-QTAS$
+## Commercial License Usage
+## Licensees holding valid commercial Qt Automotive Suite licenses may use
+## this file in accordance with the commercial license agreement provided
+## with the Software or, alternatively, in accordance with the terms
+## contained in a written agreement between you and The Qt Company. For
+## licensing terms and conditions see https://www.qt.io/terms-conditions.
+## For further information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+## SPDX-License-Identifier: GPL-3.0
+##
+#############################################################################
+
+from objectmaphelper import *
+
+neptune_UI_Center_Console = {"title": "Neptune 3 UI - Center Console", "type": "QQuickWindowQmlImpl", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_grid_GridView = {"container": neptune_UI_Center_Console, "id": "grid", "type": "GridView", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_instrumentClusterWindowLoader_Loader = {"container": neptune_UI_Center_Console, "id": "instrumentClusterWindowLoader", "type": "Loader", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_leftIcon_ToolButton = {"checkable": False, "container": neptune_UI_Center_Console, "id": "leftIcon", "type": "ToolButton", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_leftTempSlider_TemperatureSlider = {"container": neptune_UI_Center_Console, "id": "leftTempSlider", "type": "TemperatureSlider", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_rightTempSlider_TemperatureSlider = {"container": neptune_UI_Center_Console, "id": "rightTempSlider", "type": "TemperatureSlider", "unnamed": 1, "visible": True}
+o_QVariant = {"type": "QVariant"}
+neptune_UI_Instrument_Cluster_QQuickWindowQmlImpl = {"title": "Neptune 3 UI - Instrument Cluster", "type": "QQuickWindowQmlImpl", "unnamed": 1, "visible": True, "window": o_QVariant}
+grid_Item = {"container": neptune_UI_Center_Console_grid_GridView, "type": "Item", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_rightTempSlider_TemperatureSlider_2 = {"container": ":Neptune UI - Center Console_QQuickWindowQmlImpl", "id": "rightTempSlider", "type": "TemperatureSlider", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_widgetListview_ListView = {"container": neptune_UI_Center_Console, "id": "widgetListview", "type": "ListView", "unnamed": 1, "visible": True}
+widgetListview_Maps_ListItem = {"checkable": False, "container": neptune_UI_Center_Console_widgetListview_ListView, "text": "Maps", "type": "ListItem", "unnamed": 1, "visible": True}
+maps_Maps_Label = {"container": widgetListview_Maps_ListItem, "text": "Maps", "type": "Label", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_appWidget_ApplicationWidget = {"container": neptune_UI_Center_Console, "id": "appWidget", "type": "ApplicationWidget", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_grid_GridView_2 = {"container": ":Neptune UI - Center Console_QQuickWindowQmlImpl", "id": "grid", "type": "GridView", "unnamed": 1, "visible": True}
+grid_delegateRoot_MouseArea = {"container": neptune_UI_Center_Console_grid_GridView_2, "id": "delegateRoot", "index": 0, "type": "MouseArea", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_root_AddWidgetPopup = {"container": neptune_UI_Center_Console, "id": "root", "type": "AddWidgetPopup", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_homeButton_ToolButton = {"checkable": True, "container": neptune_UI_Center_Console, "id": "homeButton", "type": "ToolButton", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_root_PrimaryWindow = {"container": neptune_UI_Center_Console, "id": "root", "type": "PrimaryWindow", "unnamed": 1, "visible": True}
+neptune_UI_Center_Console_squish_on_toolbutton_ToolButton = {"container": neptune_UI_Center_Console, "id": "squish_close_button", "objectName": "squish_on_toolbutton", "type": "ToolButton", "visible": True}
+neptune_3_UI_Center_Console_squish_volumePopupButton_ToolButton = {"container": neptune_UI_Center_Console, "objectName": "squish_volumePopupButton", "type": "ToolButton", "visible": True}
+neptune_3_UI_Center_Console_squish_volumePopupItem_VolumePopup = {"container": neptune_UI_Center_Console, "objectName": "squish_volumePopupItem", "type": "VolumePopup", "visible": True}
+neptune_3_UI_Center_Console_squish_popupClose_ToolButton = {"checkable": False, "container": neptune_UI_Center_Console, "objectName": "squish_popupClose", "type": "ToolButton", "visible": True}
+neptune_3_UI_Center_Console_squish_volumeSlider_Slider = {"container": neptune_UI_Center_Console, "objectName": "squish_volumeSlider", "type": "Slider", "visible": True}
+neptune_3_UI_Center_Console_centerConsole_CenterConsole = {"container": neptune_UI_Center_Console, "id": "centerConsole", "type": "CenterConsole", "visible": True}
+neptune_3_UI_Center_Console_squish_addWidgetButton_ToolButton = {"checkable": False, "container": neptune_UI_Center_Console, "objectName": "squish_addWidgetButton", "type": "ToolButton", "visible": True}
+neptune_3_UI_Center_Console_squish_addWidgetPopupItem_AddWidgetPopup = {"container": neptune_UI_Center_Console, "objectName": "squish_addWidgetPopupItem", "type": "AddWidgetPopup", "visible": True}
+widgetList_AddWidgets_Maps = {"checkable": False, "container": neptune_UI_Center_Console_widgetListview_ListView, "objectName": "squish_itemAddWidget_com.pelagicore.map", "text": "Maps", "type": "ListItem", "visible": True}
+neptune_3_UI_Center_Console_squish_homeWidget_Maps_Column = {"container": neptune_UI_Center_Console, "objectName": "squish_homeWidget_com.pelagicore.map", "type": "Column", "visible": True}
+good_appMainMenu_WidgetClose_Map_MouseArea = {"container": neptune_UI_Center_Console, "objectName": "squish_appWidgetClose_com.pelagicore.map", "type": "MouseArea", "visible": True}
+maps_Maps_Label_2 = {"container": widgetList_AddWidgets_Maps, "text": "Maps", "type": "Label", "unnamed": 1, "visible": True}
+neptune_3_UI_Center_Console_squish_launcherCenterConsole_Launcher = {"container": neptune_UI_Center_Console, "objectName": "squish_launcher", "type": "Launcher", "visible": True}
+neptune_3_UI_Center_Console_squish_gridButton_ToolButton = {"checkable": True, "container": neptune_UI_Center_Console, "objectName": "squish_gridButton", "type": "ToolButton", "visible": True}
+neptune_3_UI_Center_Console_squish_climateBarMouseArea_MouseArea = {"container": neptune_UI_Center_Console, "objectName": "squish_climateBarMouseArea", "type": "MouseArea", "visible": True}
+neptune_3_UI_Center_Console_squish_editableLauncher_EditableGridView = {"container": neptune_UI_Center_Console, "objectName": "squish_editableLauncher", "type": "EditableGridView", "visible": True}
diff --git a/squishtests/suite_neptune3/shared/steps/essential.py b/squishtests/suite_neptune3/shared/steps/essential.py
new file mode 100644
index 00000000..8d3fcb1f
--- /dev/null
+++ b/squishtests/suite_neptune3/shared/steps/essential.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+
+############################################################################
+##
+## Copyright (C) 2018 Luxoft GmbH
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Neptune 3 IVI UI.
+##
+## $QT_BEGIN_LICENSE:GPL-QTAS$
+## Commercial License Usage
+## Licensees holding valid commercial Qt Automotive Suite licenses may use
+## this file in accordance with the commercial license agreement provided
+## with the Software or, alternatively, in accordance with the terms
+## contained in a written agreement between you and The Qt Company. For
+## licensing terms and conditions see https://www.qt.io/terms-conditions.
+## For further information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+## SPDX-License-Identifier: GPL-3.0
+##
+#############################################################################
+
+import names
+
+# coordinate
+from math import sin,cos,floor
+
+
+G_WAIT_FOR_INEXISTANCE_MS = 1000
+# waiting time for system to get ready between test scenarios todo: change somehow and distinguish between scenario and test, since no instance will appear
+G_WAIT_SYSTEM_READY_SEC = 1
+
+SCREEN_WIDTH = 1920
+SCREEN_HEIGHT = 1080
+# Landscape is ambigous: can be either rotation of 90 (pi) or 270 (3/4 pi) degrees
+# rotation yet unclear, what will be the reference system (test in portrait I'd suggest)
+SCREEN_LANDSCAPE = False
+
+SCREEN_ROTATION = 0.0 # from 0 to 2pi is clockwise
+SCREEN_SHIFT_X_px = 0
+SCREEN_SHIFT_Y_px = 0
+
+
+def coord_transform2D(src_point):
+ global G_WAIT_SYSTEM_READY_SEC # todo: put somewhere else
+ ti = QPoint(0,0)
+
+ rotation = float(0)
+ if not SCREEN_LANDSCAPE:
+ rotation = Math.pi * 0.75
+ # I misuse it to distinguish between target and test development
+ G_WAIT_SYSTEM_READY_SEC = 3
+
+ scale_x = float(SCREEN_WIDTH * 0.01)
+ scale_y = float(SCREEN_HEIGHT * 0.01)
+
+ r_sin_rho = sin(rotation)
+ r_cos_rho = cos(rotation)
+
+ # not fully tested!!!!
+ tx = float((r_cos_rho * src_point.x * scale_x) - (r_sin_rho * src_point.y * scale_y))
+ ty = float((r_sin_rho * src_point.x * scale_x) + (r_cos_rho * src_point.y * scale_y))
+
+ # do a geometric translation (after so no rotation in a point)
+ ti.x = floor(tx) + SCREEN_SHIFT_X_px
+ ti.y = floor(ty) + SCREEN_SHIFT_Y_px
+ return ti
+
+
+@Given("main menu is open")
+def step(context):
+ snooze(G_WAIT_SYSTEM_READY_SEC)
+ test.compare(True,True)
+
+@Given("main menu is focused")
+def step(context):
+ worked, _obj = focus_window("console")
+ test.compare(True, worked)
+
+# a dummy
+@When("nothing")
+def step(context):
+ test.compare(True,True)
+
+# a dummy
+@Given("nothing")
+def step(context):
+ pass
+
+# a dummy
+@Then("nothing")
+def step(context):
+ pass
+
+@Then("after some '|integer|' seconds")
+def step(context,seconds):
+ snooze(seconds)
+
+@When("after some '|integer|' seconds")
+def step(context,seconds):
+ snooze(seconds)
+
+
+# --------------------- specific not yet clear, where to put it
+@When("the popup close button is clicked")
+def step(context):
+ popup_close_button = waitForObject(names.neptune_3_UI_Center_Console_squish_popupClose_ToolButton)
+ mouseClick(popup_close_button)
+
+def is_squish_object_there(squish_object,seconds):
+ snooze(seconds)
+ try:
+ waitForObjectExists(squish_object,G_WAIT_FOR_INEXISTANCE_MS)
+ except Exception:
+ return False
+ else:
+ return True
+
+# -------------------------------------------------------
diff --git a/squishtests/suite_neptune3/shared/steps/steps.py b/squishtests/suite_neptune3/shared/steps/steps.py
new file mode 100644
index 00000000..31abf081
--- /dev/null
+++ b/squishtests/suite_neptune3/shared/steps/steps.py
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+
+############################################################################
+##
+## Copyright (C) 2018 Luxoft GmbH
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Neptune 3 IVI UI.
+##
+## $QT_BEGIN_LICENSE:GPL-QTAS$
+## Commercial License Usage
+## Licensees holding valid commercial Qt Automotive Suite licenses may use
+## this file in accordance with the commercial license agreement provided
+## with the Software or, alternatively, in accordance with the terms
+## contained in a written agreement between you and The Qt Company. For
+## licensing terms and conditions see https://www.qt.io/terms-conditions.
+## For further information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+## SPDX-License-Identifier: GPL-3.0
+##
+#############################################################################
+
+# A quick introduction to implementing scripts for BDD tests:
+#
+# This file contains snippets of script code to be executed as the .feature
+# file is processed. See the section 'Behavior Driven Testing' in the 'API
+# Reference Manual' chapter of the Squish manual for a comprehensive reference:
+#
+# https://doc.froglogic.com/squish/latest/api.bdt.functions.html
+#
+# The decorators Given/When/Then/Step can be used to associate a script snippet
+# with a pattern which is matched against the steps being executed. Optional
+# table/multi-line string arguments of the step are passed via a mandatory
+# 'context' parameter:
+#
+# @When("I enter the text")
+# def whenTextEntered(context):
+# <code here>
+#
+# The pattern is a plain string without the leading keyword ("Given",
+# "When", "Then", etc.).
+#
+# Inside of the pattern the following placeholders are supported:
+#
+# |any|
+# |word|
+# |integer|
+#
+# These placeholders can be used to extract arbitrary, alphanumeric and
+# integer values resp. from the pattern; the extracted values are passed
+# as additional arguments to the step implementation function:
+#
+# @Then("I get |integer| different names")
+# def namesReceived(context, numNames):
+# <code here>
+#
+# Instead of using a string with placeholders, a regular expression can be
+# specified. In that case, make sure to set the (optional) 'regexp' argument
+# to True:
+#
+# @Then("I get (\d+) different names", regexp=True)
+# def namesReceived(context, numNames):
+# <code here>
diff --git a/squishtests/suite_neptune3/suite.conf b/squishtests/suite_neptune3/suite.conf
new file mode 100644
index 00000000..46d64ca9
--- /dev/null
+++ b/squishtests/suite_neptune3/suite.conf
@@ -0,0 +1,11 @@
+AUT=neptune3-ui -c am-config.yaml --start-session-dbus -platform eglfs -plugin evdevkeyboard:grab=1 --logging-rule *=true --logging-rule Qt3D.*.debug=false --logging-rule=""qt.*.debug=false
+CWD=<AUT_path>
+ENVVARS=envvars
+HOOK_SUB_PROCESSES=false
+IMPLICITAUTSTART=0
+LANGUAGE=Python
+OBJECTMAP=./shared/objects.map
+OBJECTMAPSTYLE=script
+TEST_CASES=tst_environment_info tst_main_menu_widgets tst_popup_menus tst_volume_popup tst_launch_bar
+VERSION=3
+WRAPPERS=Qt