Merge lp:~cellsoftware/telegram-app/autopilotTest-4 into lp:telegram-app

Proposed by Paz Chauhan
Status: Merged
Approved by: Jin
Approved revision: 250
Merged at revision: 247
Proposed branch: lp:~cellsoftware/telegram-app/autopilotTest-4
Merge into: lp:telegram-app
Diff against target: 3409 lines (+2757/-37)
35 files modified
README.md (+191/-35)
buildScripts/click.sh (+10/-0)
setup.sh (+17/-1)
telegram/app/qml/AccountContactsPage.qml (+5/-1)
telegram/app/qml/AccountDialogList.qml (+2/-0)
telegram/app/qml/AccountDialogPage.qml (+4/-0)
telegram/app/qml/AccountMessageList.qml (+2/-0)
telegram/app/qml/AccountMessageMedia.qml (+1/-0)
telegram/app/qml/AccountPage.qml (+4/-0)
telegram/app/qml/AccountSendMessage.qml (+7/-0)
telegram/app/qml/AccountSettings.qml (+4/-0)
telegram/app/qml/AuthCountriesPage.qml (+2/-0)
telegram/app/qml/AuthNumberPage.qml (+3/-0)
telegram/app/qml/ProfilePage.qml (+14/-0)
telegram/app/qml/components/AccountPanel.qml (+4/-0)
telegram/app/qml/components/AttachPanel.qml (+4/-0)
telegram/app/qml/components/MediaImport.qml (+2/-0)
telegram/app/qml/components/MessageStatus.qml (+1/-0)
telegram/app/qml/components/MessagesListItem.qml (+3/-0)
telegram/app/qml/telegram.qml (+1/-0)
telegram/autopilot/CLI/test_receive_response.lua (+149/-0)
telegram/autopilot/telegram/common/__init__.py (+36/-0)
telegram/autopilot/telegram/common/config.py (+350/-0)
telegram/autopilot/telegram/common/options.py (+37/-0)
telegram/autopilot/telegram/common/ssh.py (+199/-0)
telegram/autopilot/telegram/common/utils.py (+87/-0)
telegram/autopilot/telegram/emulators.py (+550/-0)
telegram/autopilot/telegram/setup.py (+57/-0)
telegram/autopilot/telegram/tests/__init__.py (+76/-0)
telegram/autopilot/telegram/tests/test_Logout.py (+52/-0)
telegram/autopilot/telegram/tests/test_MessageDisplay.py (+205/-0)
telegram/autopilot/telegram/tests/test_Messaging.py (+402/-0)
telegram/autopilot/telegram/tests/test_Offline.py (+54/-0)
telegram/autopilot/telegram/tests/test_Profile.py (+186/-0)
telegram/autopilot/telegram/utilities.py (+36/-0)
To merge this branch: bzr merge lp:~cellsoftware/telegram-app/autopilotTest-4
Reviewer Review Type Date Requested Status
Jin (community) Approve
Roberto Mier Escandon (community) Approve
Review via email: mp+310414@code.launchpad.net

Description of the change

Autopilot tests added
Code changes involve adding 'objectName' attribute to necessary components in order to make them visible to autopilot
Build script updates (setup.sh and click.sh) to include new flag (-u) to include autopilot tests in click package for mobile build
README document updated with autopilot use

To post a comment you must log in.
Revision history for this message
Roberto Mier Escandon (rmescandon) wrote :

Please, fix conflicts "Text conflict in telegram/app/qml/components/MessagesListItem.qml"

review: Needs Fixing
246. By Paz Chauhan

Removal of parseText function

Revision history for this message
Paz Chauhan (paz-chauhan) wrote :

Conflicts hopefully resolved

Revision history for this message
Roberto Mier Escandon (rmescandon) wrote :

Still seen conflicts here. See just below the "Diff against target" section

review: Needs Fixing
247. By Paz Chauhan

conflicts resolved

248. By Paz Chauhan

.po and .pot files reverted

Revision history for this message
Roberto Mier Escandon (rmescandon) wrote :

Please revert also the telegram/po complete directory

review: Needs Fixing
249. By Paz Chauhan

.po and .pot files reverted

Revision history for this message
Roberto Mier Escandon (rmescandon) wrote :

Just a pair of commented out lines that I'm not sure if are there left on purpose. If not remove them, please

review: Needs Fixing
250. By Paz Chauhan

Commented out code explained

Revision history for this message
Roberto Mier Escandon (rmescandon) wrote :

My experience is that on device some of the tests pass, some others not. I have not been able to pass all them ever.
In desktop version, the textbox to write messages is disabled (I see also app in "waiting for network", so seem it is related) and thus the tests are not passing (send messages cannot be executed)

I guess all this can be fixed in a later MR. For now +1

review: Approve
Revision history for this message
Jin (jindallo) wrote :

I can't get them all passed as well,
no further actions on Contact selection page in running oftenly,
now the DUT from me is Nexus 4 with stable channel,
still need to verify it on BQ phone later,
will report my running result here.

Revision history for this message
Jin (jindallo) wrote :

After .lua configured now the test cases can run well,
I approve.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README.md'
--- README.md 2016-09-30 05:22:00 +0000
+++ README.md 2016-11-14 11:39:33 +0000
@@ -1,4 +1,4 @@
1# Telegram for Ubuntu1# **Telegram for Ubuntu**
22
3### TLDR;3### TLDR;
4 "./setup.sh -t mobile -dbc" for a full mobile build4 "./setup.sh -t mobile -dbc" for a full mobile build
@@ -7,60 +7,216 @@
7### How to build7### How to build
88
9This build setup has been tested on:9This build setup has been tested on:
10- Ubuntu Xenial 16.0410- Ubuntu Vivid 15.04 with Overlay PPA enabled
1111
12The following instructions assume you downloaded Telegram for Ubuntu source and changed ("cd") to the project's root directory.12The following instructions assume you downloaded Telegram for Ubuntu source and changed ("cd") to the project's root directory.
1313
141) Install build dependencies14## **Install build dependencies**
15 If you're building for mobile devices:15### Device
16 If you don't have a 15.04 click chroot yet:16 If you don't have a 15.04 click chroot yet:
17 sudo click chroot --arch armhf --framework ubuntu-sdk-15.04 create17
18 To install the build dependencies in the chroot:18 $ sudo click chroot --arch armhf --framework ubuntu-sdk-15.04 create
19 sudo click chroot --arch armhf --framework ubuntu-sdk-15.04 maint19
20 apt-get install libthumbnailer-qt-dev:armhf thumbnailer-service:armhf20To install the build dependencies in the chroot:
21 Else if you're building for desktop, install the build dependencies using the following command:21
22 sudo apt-get install libthumbnailer-qt-dev qml-module-ubuntu-connectivity qtdeclarative5-ubuntu-contacts0.122 $ sudo click chroot --arch armhf --framework ubuntu-sdk-15.04 maint
2323
242) Environment setup24 $ apt-get install libthumbnailer-qt-dev:armhf libthumbnailer-qt1.0:armhf thumbnailer-service:armhf
25 Change your directory into below:25
26 ~/.config/QtProject/qtcreator/ubuntu-sdk/ubuntu-sdk-15.04-armhf26### Desktop
27 then make a symbolic link bewteen qtc_chroot_wrapper and the make:27
28 ln -s /usr/share/qtcreator/ubuntu/scripts/qtc_chroot_wrapper.py make28 Install the build dependencies using the following command:
2929
303) Download and build the source of libqtelegram-aseman-edition library and TelegramQML plugin:30 $ sudo apt-get install libthumbnailer-qt-dev libthumbnailer-qt1.0 thumbnailer-service libqt5xmlpatterns5-dev qtdeclarative5-dev qtmultimedia5-dev libssl-dev
31 - Run ./setup.sh -t <build_type> -d31
32 322) Download and build the source of libqtelegram-aseman-edition library and TelegramQML plugin:
33 The help command will show the available values for <build_type>.33
34 It'll git clone both projects to the deps directory and build them (inside the click chroot, if34 $ ./setup.sh -t <build_type> -d
35 the build type chosen was "mobile").35
36 You can use same command to re-build, if you have changed them, too.36The help command will show the available values for <build_type>.
37 NOTE: it may be required to modify some environment variables that drive the build process, such37 It'll git clone both projects to the deps directory and build them (inside the click chroot, if the build type chosen was "mobile").
38You can use same command to re-build, if you have changed them, too.
39
40 NOTE: it may be required to modify some environment variables that drive the build process, such
38 as the path to qmake or make, the path to system libraries, the name of the chroot, etc.41 as the path to qmake or make, the path to system libraries, the name of the chroot, etc.
39 The env variables are grouped at the beginning of setup.sh, to make the customization easier.42 The env variables are grouped at the beginning of setup.sh, to make the customization easier.
40 43
414) Build Telegram for Ubuntu443) Build Telegram for Ubuntu
42 - Run ./setup.sh -t <build_type> -b45
46 $ ./setup.sh -t <build_type> -b
43 47
44 This will build the app in the build path defined by setup.sh 48 This will build the app in the build path defined by setup.sh
45 and prepare everything in a directory named click in the project's root directory.49 and prepare everything in a directory named click in the project's root directory.
46 NOTE: it may be required to modify some environment variables that drive the build process, such50 NOTE: it may be required to modify some environment variables that drive the build process, such
47 as the path to qmake or make, the path to system libraries, the name of the chroot, etc.51 as the path to qmake or make, the path to system libraries, the name of the chroot, etc.
48 The env variables are grouped at the beginning of setup.sh, to make the customization easier.52 The env variables are grouped at the beginning of setup.sh, to make the customization easier.
49 53
505) (Optional) Build the click package and install it using adb (requires an Ubuntu Touch 544) (Optional) Build the click package and install it using adb (requires an Ubuntu Touch
51 mobile device connected via USB with developer mode enabled):55 mobile device connected via USB with developer mode enabled):
52 - Run ./setup.sh -t mobile -c
53 56
57 $ ./setup.sh -t mobile -c
54 58
55### How to run (DESKTOP VERSION only)59### How to run (DESKTOP VERSION only)
5660
57- cd to the path holding the binary we have just build, e.g. "cd build_desktop/lib/x86_64-linux-gnu/bin/"61cd to the path holding the binary we have just build, e.g. `$ cd build_desktop/lib/x86_64-linux-gnu/bin/`
58- run "LD_LIBRARY_PATH=../../../:$LD_LIBRARY_PATH ./telegram"62
63 $ LD_LIBRARY_PATH=../../../:$LD_LIBRARY_PATH ./telegram
64
5965
60### How to delete the build files66### How to delete the build files
6167
62- Run ./setup -t <build_type> -e68 $ ./setup -t <build_type> -e
6369
64### How to get help70### How to get help
6571
66- Run ./setup -h72 $ ./setup -h
73
74----------
75
76# **Autopilot**
77
78### Install On Desktop
79To install Autopilot on a Ubuntu Desktop follow [this tutorial](https://developer.ubuntu.com/api/autopilot/python/1.5.0/guides-installation/).
80
81### Install on Device
82To install on a Ubuntu device you will need to first connect to the device via SSH:
83
84 $ adb shell
85
86Then execute the following commands:
87
88 $ sudo mount -o remount,rw /
89
90 $ sudo apt-get update
91
92 $ sudo apt-get install python3-autopilot ubuntu-ui-toolkit-autopilot -yq
93
94## **Telegram-App code changes**
95Download the following telegram-app sample project which contains the autopilot test cases and and supporting documentation such as, **Telegram-App_Code_Changes.pdf**:
96
97 $ bzr branch lp:~cellsoftware/telegram-app/autopilotTest-3
98
99**Telegram-App_Code_Changes.pdf** lists the components which need to be updated, on your on version of the telegram-app code, with the *objectName* attribute in order for them to become visible to autopilot. This document also describes certain code changes which need to be made in order for desktop tests to pass. These are mainly to do with simulating an online device.
100
101Once downloaded, you will have created and autopilotTest-3 directory on your computer. The autopilot test scripts for **telegram-app** can be found in the following relative directory path:
102
103> autopilotTest-3/telegram/autopilot/telegram
104
105**This directory structure must be maintained when copying the autopilot test cases to your own version of the app.**
106
107##**Test Environment**
108
109###Telegram-CLI
110All tests involving the sending and receiving of messages will involve the Telegram CLI. This can be downloaded from [GitHub](https://github.com/vysheng/tg). Follow the instructions to install and build. The Telegram CLI scripts are written in Lua and can be found in the following relative directory path:
111
112> autopilotTest-3/telegram/autopilot/CLI
113
114**This directory structure must be maintained when copying the autopilot test cases to your own version of the app.**
115
116#### Telegram CLI Launch
117
118Once downloaded cd, to the '**tg**' folder. Then execute the following command:
119
120 $ bin/telegram-cli -k tg-server.pub -W -s <location of the test script>
121
122###Test Data
123The following are prerequisites to executing the autopilot test cases:
124
125> - A Telegram user must be logged into the app
126> - The Telegram user must be signed into their Ubuntu One account
127> - The app must not be launched
128> - The device must not be screen or SIM locked
129> - The device must be on the screen displaying the apps
130> - The user must have 2 Telegram contacts defined, one of which must be the phone number used to set up the Telegram CLI
131> - The Telegram CLI must be online
132
133## **Execution**
134
135### Desktop
136
137Before running, the **telegram-app** and its dependencies have to be built.
138From the autopilotTest-3 directory execute the following command:
139
140 $ ./setup.sh -t desktop -db
141
142To execute the entire test suite perform the following command from the `autopilotTest-3/telegram/autopilot/` directory:
143
144 $ autopilot3 run telegram/
145
146To get a list of all individual test cases execute the following command:
147
148 $ autopilot3 list telegram/
149
150You will see an output similar to this:
151
152> *2 telegram.tests.test_Messaging.SecretMessaging.test_SecretMessage
153> telegram.tests.test_Profile.ProfileTests.test_check_group_to_verify_members
154> telegram.tests.test_Profile.ProfileDetails.test_verify_profile_details
155> telegram.tests.test_Profile.ProfileTests.test_check_blocked_user
156
157The *2 next to a test case refers to the number of scenarios within that test case. Therefore executing test_SecretMessage will run the same Secret Message test case but for 2 scenarios, e.g. sending a Secret Message containing text only and sending a Secret Message containing images only.
158
159To execute all Profile tests execute the following:
160
161 $ autopilot3 run telegram.tests.test_Profile
162
163To execute all Profile Detail tests, execute the following:
164
165 $ autopilot3 run telegram.tests.test_Profile.ProfileDetails
166
167To execute individual tests choose a test from the list, for example *telegram.tests.test_Login.Login.test_sign_in* then execute the following command:
168
169 $ autopilot3 run telegram.tests.test_Login.Login.test_sign_in
170
171### Device
172
173To execute the autopilot test cases on a device, the **telegram-app**, its dependencies and the click package have to be built and installed on the device. Once you have connected your device via USB, build the mobile version of the app using the following command:
174
175 $ ./setup.sh -t mobile -dbcu
176
177Next, navigate to the installed test suite using:
178
179 $ adb shell
180
181 $ cd /opt/click.ubuntu.com/com.ubuntu.telegram/current/autopilot
182
183The listing and executing of tests are as described in the Desktop section.
184
185## **Notes**
186After getting Autopilot working. Here are some notes you need to do to ensure tests can be run properly:
187
188### Device
189
190During device testing the orientation should remain as portrait. Changing the orientation to landscape will cause tests to fail.
191
192### Telegram CLI
193
194If any of the test cases executed require the sending and/or receiving of messages the Telegram CLI will have to be launched, as described above. If left running for some time without activity the Telegram CLI will go offline. This may cause some autopilot tests to fail. To bring the Telegram CLI back online you can issue a CLI command, or quit the CLI by entering 'safe_quit' and relaunching.
195
196### Flags
197
198Here are the types and meanings for each flag:
199
200**-d** - Dependency - Build the dependency to support the app
201**-b** - Build - Builds and compile the app.
202**-c** - Install on device
203**-u** - Adds the autopilot tests to the click package installed on the device
204
205 $ ./setup.sh -t mobile -<flag(s)>
206For a more in-depth 'how-to' see [here](https://developer.ubuntu.com/api/autopilot/python/1.5.0/guides-running_ap/).
207
208###Messaging
209To get messaging working correctly you need to make some code changes in
210AccountSendMessage.qml:
211
212> 1. Enable TextArea - #155 - Change to `enabled: true`.
213> 2. Enable Sticker button (if required) - #264 - Remove `connected || !NetworkingStatus` IF statement so you only have `if
214> (!privates.emojiItem) {...}` in `onClicked:`.
215> 3. Enable Send button - #326 - Remove `connected || !NetworkingStatus` IF statement so you only have `if (state == “attach”) {...}` in
216> `onClicked:`.
217
218## **References & Tutorials**
219- [Autopilot Tutorials and Guides](https://developer.ubuntu.com/api/autopilot/python/1.5.0/)
220- [Autopilot at a glance](http://www.theorangenotebook.com/2012/11/a-glance-at-autopilot.html)
221- [Getting started with Autopilot](http://www.theorangenotebook.com/2012/11/getting-started-with-autopilot.html)
222- [Your first autopilot test case](http://www.theorangenotebook.com/2012/11/our-first-autopilot-testcase.html)
67223
=== added file 'Telegram-App_Code_Changes.pdf'
68Binary files Telegram-App_Code_Changes.pdf 1970-01-01 00:00:00 +0000 and Telegram-App_Code_Changes.pdf 2016-11-14 11:39:33 +0000 differ224Binary files Telegram-App_Code_Changes.pdf 1970-01-01 00:00:00 +0000 and Telegram-App_Code_Changes.pdf 2016-11-14 11:39:33 +0000 differ
=== modified file 'buildScripts/click.sh'
--- buildScripts/click.sh 2015-11-02 15:30:52 +0000
+++ buildScripts/click.sh 2016-11-14 11:39:33 +0000
@@ -6,6 +6,16 @@
6 exit 16 exit 1
7fi7fi
88
9if [ "$TEST_STEP" = "y" ]; then
10 # Copy autopilot tests into click directory
11 echo "Removing old autopilot tests..."
12 rm -rf $TG_DIR/$BUILD_DIR_BASENAME/click/$AUTOPILOT_DIR || exit 1
13 echo "Adding autopilot tests to the click package..."
14 mkdir $TG_DIR/$BUILD_DIR_BASENAME/click/$AUTOPILOT_DIR || exit 1
15 # mkdir $TG_DIR/$BUILD_DIR_BASENAME/click/$AUTOPILOT_DIR_BASENAME || exit 1
16 cp -avr $TG_DIR/$AUTOPILOT_PATH $TG_DIR/$BUILD_DIR_BASENAME/click/$AUTOPILOT_DIR_BASENAME || exit 1
17fi
18
9cd $TG_DIR/$BUILD_DIR_BASENAME/ || exit 119cd $TG_DIR/$BUILD_DIR_BASENAME/ || exit 1
10click build click || exit 120click build click || exit 1
1121
1222
=== modified file 'setup.sh'
--- setup.sh 2016-04-01 08:44:31 +0000
+++ setup.sh 2016-11-14 11:39:33 +0000
@@ -37,6 +37,10 @@
37 export SYSTEM_LIB_PATH=/usr/lib/arm-linux-gnueabihf37 export SYSTEM_LIB_PATH=/usr/lib/arm-linux-gnueabihf
38 export SYSTEM_INCLUDE_PATH=/usr/include/38 export SYSTEM_INCLUDE_PATH=/usr/include/
39 export BUILD_DIR_BASENAME=build_mobile39 export BUILD_DIR_BASENAME=build_mobile
40 export AUTOPILOT_DIR=autopilot
41 export AUTOPILOT_APP_DIR=/telegram
42 export AUTOPILOT_DIR_BASENAME=$AUTOPILOT_DIR/$AUTOPILOT_APP_DIR
43 export AUTOPILOT_PATH=telegram/$AUTOPILOT_DIR_BASENAME
40}44}
41#Generic env vars45#Generic env vars
42function setTelegramEnvVars() {46function setTelegramEnvVars() {
@@ -65,6 +69,7 @@
65APP_STEP=n69APP_STEP=n
66CLICK_STEP=n70CLICK_STEP=n
67ERASE_STEP=n71ERASE_STEP=n
72export TEST_STEP=n
68RESET_ENV_VARS=n73RESET_ENV_VARS=n
6974
70function usage() {75function usage() {
@@ -75,9 +80,10 @@
75 echo "-b To build the telegram app."80 echo "-b To build the telegram app."
76 echo "-c To create and install the click package (only valid if mobile build type has been selected)"81 echo "-c To create and install the click package (only valid if mobile build type has been selected)"
77 echo "-e To erase all build files relative to the specified build type."82 echo "-e To erase all build files relative to the specified build type."
83 echo "-u To include all autopilot unit test cases in the click package (only valid if -c has been selected)."
78}84}
7985
80while getopts "t:dbceh" opt; do86while getopts "t:dbceuh" opt; do
81 case $opt in87 case $opt in
82 t)88 t)
83 case $OPTARG in89 case $OPTARG in
@@ -106,6 +112,9 @@
106 e)112 e)
107 ERASE_STEP=y113 ERASE_STEP=y
108 ;;114 ;;
115 u)
116 TEST_STEP=y
117 ;;
109 v)118 v)
110 RESET_ENV_VARS=y119 RESET_ENV_VARS=y
111 ;;120 ;;
@@ -125,6 +134,12 @@
125 exit 1134 exit 1
126fi135fi
127136
137if [ "$CLICK_STEP" = "n" ] && [ "$TEST_STEP" = "y" ]; then
138 echo "The inclusion of autopilot test cases requires the -c flag."
139 usage
140 exit 1
141fi
142
128if [ "$BUILD_TYPE" = "desktop" ]; then143if [ "$BUILD_TYPE" = "desktop" ]; then
129 setDesktopBuildEnvVars144 setDesktopBuildEnvVars
130else 145else
@@ -167,3 +182,4 @@
167if [ "$ERASE_STEP" = "y" ]; then182if [ "$ERASE_STEP" = "y" ]; then
168 source ./buildScripts/clean.sh || exit 1183 source ./buildScripts/clean.sh || exit 1
169fi184fi
185
170186
=== modified file 'telegram/app/qml/AccountContactsPage.qml'
--- telegram/app/qml/AccountContactsPage.qml 2016-06-17 15:19:54 +0000
+++ telegram/app/qml/AccountContactsPage.qml 2016-11-14 11:39:33 +0000
@@ -17,7 +17,7 @@
17Page {17Page {
18 id: page18 id: page
19 flickable: null19 flickable: null
2020 objectName: "accountContactsPage"
21 header: default_header21 header: default_header
2222
23 PageHeader {23 PageHeader {
@@ -113,6 +113,7 @@
113 property var none: []113 property var none: []
114 property list<Action> confirm: [114 property list<Action> confirm: [
115 Action {115 Action {
116 objectName: "createGroupChatOK"
116 iconName: "ok"117 iconName: "ok"
117 text: i18n.tr("OK")118 text: i18n.tr("OK")
118 enabled: hasGroupTitle119 enabled: hasGroupTitle
@@ -225,6 +226,7 @@
225226
226 TextField {227 TextField {
227 id: group_chat_title_text_field228 id: group_chat_title_text_field
229 objectName: "groupChatTextField"
228 anchors {230 anchors {
229 top: page.header.bottom231 top: page.header.bottom
230 topMargin: isVisible ? units.gu(1) : 0232 topMargin: isVisible ? units.gu(1) : 0
@@ -253,6 +255,7 @@
253 }255 }
254256
255 MultipleSelectionListView {257 MultipleSelectionListView {
258 objectName: "contactList"
256 id: contact_list259 id: contact_list
257 anchors {260 anchors {
258 top: group_chat_title_text_field.visible ? group_chat_title_text_field.bottom : parent.top261 top: group_chat_title_text_field.visible ? group_chat_title_text_field.bottom : parent.top
@@ -278,6 +281,7 @@
278281
279 listModel: searchTerm == "" ? contacts_model : contacts_filter_model282 listModel: searchTerm == "" ? contacts_model : contacts_filter_model
280 listDelegate: TelegramContactsListItem {283 listDelegate: TelegramContactsListItem {
284 objectName: "contact%1".arg(index)
281 id: delegate285 id: delegate
282 telegram: page.telegram286 telegram: page.telegram
283 user: model.user287 user: model.user
284288
=== modified file 'telegram/app/qml/AccountDialogList.qml'
--- telegram/app/qml/AccountDialogList.qml 2016-07-19 15:15:28 +0000
+++ telegram/app/qml/AccountDialogList.qml 2016-11-14 11:39:33 +0000
@@ -57,6 +57,7 @@
5757
58 ListView {58 ListView {
59 id: dialog_list59 id: dialog_list
60 objectName: "dialogListView"
60 anchors {61 anchors {
61 top: parent.top62 top: parent.top
62 left: parent.left63 left: parent.left
@@ -81,6 +82,7 @@
8182
82 delegate: DialogsListItem {83 delegate: DialogsListItem {
83 id: list_item84 id: list_item
85 objectName: "dialog%1".arg(index)
84 anchors {86 anchors {
85 topMargin: units.dp(3)87 topMargin: units.dp(3)
86 leftMargin: units.dp(5)88 leftMargin: units.dp(5)
8789
=== modified file 'telegram/app/qml/AccountDialogPage.qml'
--- telegram/app/qml/AccountDialogPage.qml 2016-07-22 06:27:59 +0000
+++ telegram/app/qml/AccountDialogPage.qml 2016-11-14 11:39:33 +0000
@@ -28,6 +28,7 @@
2828
29 property list<Action> defaultActions: [29 property list<Action> defaultActions: [
30 Action {30 Action {
31 objectName: "groupInfo"
31 iconName: "stock_contact"32 iconName: "stock_contact"
32 text: isChat ? i18n.tr("Group Info") : i18n.tr("Profile Info")33 text: isChat ? i18n.tr("Group Info") : i18n.tr("Profile Info")
33 onTriggered: {34 onTriggered: {
@@ -85,6 +86,7 @@
85 trailingActionBar.actions: message_list.inSelectionMode ? selectionActions : defaultActions86 trailingActionBar.actions: message_list.inSelectionMode ? selectionActions : defaultActions
86 leadingActionBar.actions: Action {87 leadingActionBar.actions: Action {
87 id: back_action88 id: back_action
89 objectName: "dialogBack"
88 iconName: message_list.inSelectionMode ? "close" : "back"90 iconName: message_list.inSelectionMode ? "close" : "back"
89 onTriggered: {91 onTriggered: {
90 if (message_list.inSelectionMode) {92 if (message_list.inSelectionMode) {
@@ -213,6 +215,7 @@
213215
214 AccountSendMessage {216 AccountSendMessage {
215 id: send_msg217 id: send_msg
218 objectName: "accountSendMessageArea"
216 anchors {219 anchors {
217 right: parent.right220 right: parent.right
218 bottom: parent.bottom221 bottom: parent.bottom
@@ -236,6 +239,7 @@
236239
237 AccountMessageList {240 AccountMessageList {
238 id: message_list241 id: message_list
242 objectName: "accountMessageList"
239 anchors {243 anchors {
240 top: add_contact_header.visible ? add_contact_header.bottom : parent.top244 top: add_contact_header.visible ? add_contact_header.bottom : parent.top
241 right: parent.right245 right: parent.right
242246
=== modified file 'telegram/app/qml/AccountMessageList.qml'
--- telegram/app/qml/AccountMessageList.qml 2016-11-14 02:59:38 +0000
+++ telegram/app/qml/AccountMessageList.qml 2016-11-14 11:39:33 +0000
@@ -176,6 +176,7 @@
176176
177 MultipleSelectionListView {177 MultipleSelectionListView {
178 id: mlist178 id: mlist
179 objectName: "messagesListView"
179 anchors.fill: parent180 anchors.fill: parent
180 cacheBuffer: units.gu(10) * 20181 cacheBuffer: units.gu(10) * 20
181 clip: true182 clip: true
@@ -228,6 +229,7 @@
228 listModel: messages_model229 listModel: messages_model
229 listDelegate: MessagesListItem {230 listDelegate: MessagesListItem {
230 id: message_item231 id: message_item
232 objectName: "message%1".arg(index)
231 maximumMediaHeight: acc_msg_list.maximumMediaHeight233 maximumMediaHeight: acc_msg_list.maximumMediaHeight
232 maximumMediaWidth: acc_msg_list.maximumMediaWidth234 maximumMediaWidth: acc_msg_list.maximumMediaWidth
233 message: item235 message: item
234236
=== modified file 'telegram/app/qml/AccountMessageMedia.qml'
--- telegram/app/qml/AccountMessageMedia.qml 2016-09-28 18:34:44 +0000
+++ telegram/app/qml/AccountMessageMedia.qml 2016-11-14 11:39:33 +0000
@@ -315,6 +315,7 @@
315315
316 MessageStatus {316 MessageStatus {
317 id: message_status317 id: message_status
318 objectName: "mediaMessageStatus"
318 anchors {319 anchors {
319 bottom: parent.bottom320 bottom: parent.bottom
320 bottomMargin: units.dp(4)321 bottomMargin: units.dp(4)
321322
=== modified file 'telegram/app/qml/AccountPage.qml'
--- telegram/app/qml/AccountPage.qml 2016-07-11 16:11:59 +0000
+++ telegram/app/qml/AccountPage.qml 2016-11-14 11:39:33 +0000
@@ -75,6 +75,7 @@
7575
76 AccountPanel {76 AccountPanel {
77 id: account_panel77 id: account_panel
78 objectName:"accountPanel"
78 anchors {79 anchors {
79 left: parent.left80 left: parent.left
80 top: parent.top81 top: parent.top
@@ -168,6 +169,7 @@
168169
169 AccountDialogList {170 AccountDialogList {
170 id: dialogs171 id: dialogs
172 objectName: "accountDialogList"
171 anchors{173 anchors{
172 fill: parent174 fill: parent
173 topMargin: account_page.header.height175 topMargin: account_page.header.height
@@ -289,6 +291,7 @@
289 header: default_header291 header: default_header
290 PageHeader {292 PageHeader {
291 id: default_header293 id: default_header
294 objectName: "defaultHeader"
292 visible: account_page.header === default_header295 visible: account_page.header === default_header
293 title: {296 title: {
294 if (NetworkingStatus.online) {297 if (NetworkingStatus.online) {
@@ -305,6 +308,7 @@
305 }308 }
306 }309 }
307 leadingActionBar.actions: Action {310 leadingActionBar.actions: Action {
311 objectName: "navigationMenu"
308 iconName: "navigation-menu"312 iconName: "navigation-menu"
309 onTriggered: {313 onTriggered: {
310 account_panel.opened ? account_panel.close() : account_panel.open()314 account_panel.opened ? account_panel.close() : account_panel.open()
311315
=== modified file 'telegram/app/qml/AccountSendMessage.qml'
--- telegram/app/qml/AccountSendMessage.qml 2016-04-22 10:35:16 +0000
+++ telegram/app/qml/AccountSendMessage.qml 2016-11-14 11:39:33 +0000
@@ -139,6 +139,7 @@
139139
140 TextArea {140 TextArea {
141 id: txt141 id: txt
142 objectName: "sendMessageTextArea"
142143
143 property int oldLength: 0144 property int oldLength: 0
144145
@@ -152,6 +153,9 @@
152153
153 // This value is to avoid letter and underline being cut off.154 // This value is to avoid letter and underline being cut off.
154 height: units.gu(4.3)155 height: units.gu(4.3)
156
157 // To work on desktop change the following line to:
158 // enabled: True
155 enabled: NetworkingStatus.online && telegramObject.connected159 enabled: NetworkingStatus.online && telegramObject.connected
156 visible: !messagePlaceholder.visible160 visible: !messagePlaceholder.visible
157 // TRANSLATORS: Placeholder for the message input text area.161 // TRANSLATORS: Placeholder for the message input text area.
@@ -297,6 +301,7 @@
297301
298 MouseArea {302 MouseArea {
299 id: send_mouse_area303 id: send_mouse_area
304 objectName: "sendMouseArea"
300 height: parent.height305 height: parent.height
301 width: units.gu(6)306 width: units.gu(6)
302 enabled: telegramObject.connected307 enabled: telegramObject.connected
@@ -323,6 +328,8 @@
323 onClicked: {328 onClicked: {
324 Qt.inputMethod.commit();329 Qt.inputMethod.commit();
325330
331 // To work on desktop change the following line to:
332 // if (!telegramObject.connected) return
326 if (!telegramObject.connected || !NetworkingStatus.online) return333 if (!telegramObject.connected || !NetworkingStatus.online) return
327334
328 if (state == "attach") {335 if (state == "attach") {
329336
=== modified file 'telegram/app/qml/AccountSettings.qml'
--- telegram/app/qml/AccountSettings.qml 2016-07-13 09:13:36 +0000
+++ telegram/app/qml/AccountSettings.qml 2016-11-14 11:39:33 +0000
@@ -194,6 +194,7 @@
194 }194 }
195195
196 ListItem.Standard {196 ListItem.Standard {
197 objectName: "listItem_logout"
197 showDivider: true198 showDivider: true
198 text: i18n.tr("Log out") + " | " + telegram.phoneNumber199 text: i18n.tr("Log out") + " | " + telegram.phoneNumber
199 onClicked: PopupUtils.open(logout_dialog_component)200 onClicked: PopupUtils.open(logout_dialog_component)
@@ -282,6 +283,7 @@
282 }283 }
283284
284 ListView {285 ListView {
286 objectName: "settingsList"
285 anchors {287 anchors {
286 topMargin: units.gu(2)288 topMargin: units.gu(2)
287 top: profile_image.bottom289 top: profile_image.bottom
@@ -297,9 +299,11 @@
297 id: logout_dialog_component299 id: logout_dialog_component
298 Popup.Dialog {300 Popup.Dialog {
299 id: logout_dialog301 id: logout_dialog
302 objectName: "logoutDialog"
300 title: i18n.tr("Telegram")303 title: i18n.tr("Telegram")
301 text: i18n.tr("Are you sure you want to log out?\nAny secret chats will be lost.")304 text: i18n.tr("Are you sure you want to log out?\nAny secret chats will be lost.")
302 Button {305 Button {
306 objectName: "logoutConfirm"
303 text: i18n.tr("OK")307 text: i18n.tr("OK")
304 color: UbuntuColors.orange308 color: UbuntuColors.orange
305 onClicked: {309 onClicked: {
306310
=== modified file 'telegram/app/qml/AuthCountriesPage.qml'
--- telegram/app/qml/AuthCountriesPage.qml 2016-06-22 09:29:10 +0000
+++ telegram/app/qml/AuthCountriesPage.qml 2016-11-14 11:39:33 +0000
@@ -22,6 +22,7 @@
22 property bool searchMode: false22 property bool searchMode: false
23 Action {23 Action {
24 id: searchAction24 id: searchAction
25 objectName: "searchIcon"
25 iconName: "search";26 iconName: "search";
26 text: i18n.tr("Search");27 text: i18n.tr("Search");
27 onTriggered:{28 onTriggered:{
@@ -48,6 +49,7 @@
4849
49 TextField {50 TextField {
50 id: search_text_field51 id: search_text_field
52 objectName: "countryField"
51 visible: choose_header.searchMode53 visible: choose_header.searchMode
52 anchors {54 anchors {
53 right: parent ? parent.right : undefined55 right: parent ? parent.right : undefined
5456
=== modified file 'telegram/app/qml/AuthNumberPage.qml'
--- telegram/app/qml/AuthNumberPage.qml 2016-06-23 07:07:53 +0000
+++ telegram/app/qml/AuthNumberPage.qml 2016-11-14 11:39:33 +0000
@@ -84,6 +84,9 @@
84 height: phone_number.height84 height: phone_number.height
85 anchors.horizontalCenter: parent.horizontalCenter85 anchors.horizontalCenter: parent.horizontalCenter
86 text: i18n.tr("Done")86 text: i18n.tr("Done")
87
88 // To work on desktop change the following line to:
89 // enabled: phoneNumber.length > 0
87 enabled: isOnline && phoneNumber.length > 090 enabled: isOnline && phoneNumber.length > 0
88 focus: true91 focus: true
89 onClicked: phone_number.accepted()92 onClicked: phone_number.accepted()
9093
=== modified file 'telegram/app/qml/ProfilePage.qml'
--- telegram/app/qml/ProfilePage.qml 2016-06-27 09:22:33 +0000
+++ telegram/app/qml/ProfilePage.qml 2016-11-14 11:39:33 +0000
@@ -17,6 +17,7 @@
17Page {17Page {
18 id: profile_page18 id: profile_page
19 title: isChat ? i18n.tr("Group Info") : i18n.tr("Contact Info")19 title: isChat ? i18n.tr("Group Info") : i18n.tr("Contact Info")
20 objectName: "profilePage"
2021
21 property Telegram telegram22 property Telegram telegram
22 property Dialog dialog23 property Dialog dialog
@@ -59,6 +60,12 @@
59 header: PageHeader {60 header: PageHeader {
60 title: profile_page.title61 title: profile_page.title
61 trailingActionBar.actions: isChat ? groupActions : noActions62 trailingActionBar.actions: isChat ? groupActions : noActions
63 leadingActionBar.actions: Action {
64 id: back_action
65 objectName: "profileBack"
66 iconName: "back"
67 onTriggered: pageStack.removePages(profile_page);
68 }
62 }69 }
6370
64 signal openDialog(var dialogId)71 signal openDialog(var dialogId)
@@ -186,6 +193,7 @@
186193
187 MediaImport {194 MediaImport {
188 id: photo_importer195 id: photo_importer
196 objectName: "profileImageImport"
189 contentType: ContentType.Pictures197 contentType: ContentType.Pictures
190198
191 onMediaReceived: {199 onMediaReceived: {
@@ -235,6 +243,7 @@
235243
236 ClickableContactImage {244 ClickableContactImage {
237 id: profile_image245 id: profile_image
246 objectName: "profileImage"
238 anchors {247 anchors {
239 top: parent.top248 top: parent.top
240 topMargin: units.gu(2) + profile_page.header.height249 topMargin: units.gu(2) + profile_page.header.height
@@ -388,6 +397,7 @@
388 spacing: units.dp(4)397 spacing: units.dp(4)
389398
390 Label {399 Label {
400 objectName: "profilePhoneNumber"
391 verticalAlignment: Text.AlignVCenter401 verticalAlignment: Text.AlignVCenter
392 horizontalAlignment: Text.AlignLeft402 horizontalAlignment: Text.AlignLeft
393 fontSize: "large"403 fontSize: "large"
@@ -449,6 +459,7 @@
449 spacing: units.dp(4)459 spacing: units.dp(4)
450460
451 Label {461 Label {
462 objectName: "profileUserName"
452 id: username_label463 id: username_label
453 fontSize: "large"464 fontSize: "large"
454 font.family: "Helvetica"465 font.family: "Helvetica"
@@ -621,6 +632,7 @@
621632
622 Switch {633 Switch {
623 id: block_check634 id: block_check
635 objectName: "switchBlock"
624636
625 property bool silentChecked637 property bool silentChecked
626 property bool override: false638 property bool override: false
@@ -656,6 +668,7 @@
656668
657 ListView {669 ListView {
658 id: participants_list670 id: participants_list
671 objectName: "memberListView"
659 anchors {672 anchors {
660 top: blocked_row.bottom673 top: blocked_row.bottom
661 topMargin: units.gu(2)674 topMargin: units.gu(2)
@@ -669,6 +682,7 @@
669 model: chat_participants_model682 model: chat_participants_model
670 delegate: TelegramContactsListItem {683 delegate: TelegramContactsListItem {
671 id: contact_item684 id: contact_item
685 objectName: "dialog%1".arg(index)
672 telegram: profile_page.telegram686 telegram: profile_page.telegram
673 user: telegram.user(item.userId)687 user: telegram.user(item.userId)
674688
675689
=== modified file 'telegram/app/qml/components/AccountPanel.qml'
--- telegram/app/qml/components/AccountPanel.qml 2016-04-08 06:26:31 +0000
+++ telegram/app/qml/components/AccountPanel.qml 2016-11-14 11:39:33 +0000
@@ -72,6 +72,7 @@
72 }72 }
7373
74 AccountPanelItem {74 AccountPanelItem {
75 objectName:"groupChatItem"
75 icon: "../files/menu_newgroup.png"76 icon: "../files/menu_newgroup.png"
76 text: i18n.tr("New Group")77 text: i18n.tr("New Group")
77 showDivider: false78 showDivider: false
@@ -81,6 +82,7 @@
81 }82 }
82 }83 }
83 AccountPanelItem {84 AccountPanelItem {
85 objectName:"secretChatItem"
84 icon: "../files/menu_secret.png"86 icon: "../files/menu_secret.png"
85 text: i18n.tr("New Secret Chat")87 text: i18n.tr("New Secret Chat")
86 onClicked: {88 onClicked: {
@@ -89,6 +91,7 @@
89 }91 }
90 }92 }
91 AccountPanelItem {93 AccountPanelItem {
94 objectName:"panelContacts"
92 icon: "../files/menu_contacts.png"95 icon: "../files/menu_contacts.png"
93 text: i18n.tr("Contacts")96 text: i18n.tr("Contacts")
94 showDivider: false97 showDivider: false
@@ -98,6 +101,7 @@
98 }101 }
99 }102 }
100 AccountPanelItem {103 AccountPanelItem {
104 objectName:"panelSettings"
101 icon: "../files/menu_settings.png"105 icon: "../files/menu_settings.png"
102 text: i18n.tr("Settings")106 text: i18n.tr("Settings")
103 showDivider: false107 showDivider: false
104108
=== modified file 'telegram/app/qml/components/AttachPanel.qml'
--- telegram/app/qml/components/AttachPanel.qml 2015-10-01 14:19:18 +0000
+++ telegram/app/qml/components/AttachPanel.qml 2016-11-14 11:39:33 +0000
@@ -81,6 +81,7 @@
81 spacing: units.gu(2.8)81 spacing: units.gu(2.8)
8282
83 AttachPanelItem {83 AttachPanelItem {
84 objectName: "panelPhoto"
84 id: attach_photo_item85 id: attach_photo_item
85 // TRANSLATORS: Used in attach menu, when sending a photo to the conversation.86 // TRANSLATORS: Used in attach menu, when sending a photo to the conversation.
86 text: i18n.tr("Photo")87 text: i18n.tr("Photo")
@@ -94,6 +95,7 @@
9495
95 AttachPanelItem {96 AttachPanelItem {
96 // TRANSLATORS: Used in attach menu, when sending a video to the conversation.97 // TRANSLATORS: Used in attach menu, when sending a video to the conversation.
98 objectName: "panelVideo"
97 text: i18n.tr("Video")99 text: i18n.tr("Video")
98 image: Qt.resolvedUrl("qrc:/qml/files/android/attach_video.png")100 image: Qt.resolvedUrl("qrc:/qml/files/android/attach_video.png")
99 onClicked: {101 onClicked: {
@@ -105,6 +107,7 @@
105107
106 AttachPanelItem {108 AttachPanelItem {
107 // TRANSLATORS: Used in attach menu, when sending a file to the conversation.109 // TRANSLATORS: Used in attach menu, when sending a file to the conversation.
110 objectName: "panelFile"
108 text: i18n.tr("File")111 text: i18n.tr("File")
109 image: Qt.resolvedUrl("qrc:/qml/files/android/attach_file.png")112 image: Qt.resolvedUrl("qrc:/qml/files/android/attach_file.png")
110 onClicked: {113 onClicked: {
@@ -115,6 +118,7 @@
115 }118 }
116119
117 AttachPanelItem {120 AttachPanelItem {
121 objectName: "panelClose"
118 height: attach_photo_item.height122 height: attach_photo_item.height
119 // TRANSLATORS: Used in attach menu, when sending a file to the conversation.123 // TRANSLATORS: Used in attach menu, when sending a file to the conversation.
120 image: Qt.resolvedUrl("qrc:/qml/files/android/attach_hide1.png")124 image: Qt.resolvedUrl("qrc:/qml/files/android/attach_hide1.png")
121125
=== modified file 'telegram/app/qml/components/MediaImport.qml'
--- telegram/app/qml/components/MediaImport.qml 2016-04-08 06:08:04 +0000
+++ telegram/app/qml/components/MediaImport.qml 2016-11-14 11:39:33 +0000
@@ -40,6 +40,7 @@
4040
41 Popups.PopupBase {41 Popups.PopupBase {
42 id: dialogue42 id: dialogue
43 objectName: "mediaImportPopup"
4344
44 property alias activeTransfer: signalConnections.target45 property alias activeTransfer: signalConnections.target
45 focus: true46 focus: true
@@ -49,6 +50,7 @@
4950
50 ContentHub.ContentPeerPicker {51 ContentHub.ContentPeerPicker {
51 id: peerPicker52 id: peerPicker
53 objectName: "contentPeerPicker"
5254
53 anchors.fill: parent55 anchors.fill: parent
54 contentType: root.contentType56 contentType: root.contentType
5557
=== modified file 'telegram/app/qml/components/MessageStatus.qml'
--- telegram/app/qml/components/MessageStatus.qml 2016-05-11 10:18:15 +0000
+++ telegram/app/qml/components/MessageStatus.qml 2016-11-14 11:39:33 +0000
@@ -52,6 +52,7 @@
5252
53 Image {53 Image {
54 id: status_image54 id: status_image
55 objectName: "statusImage"
55 anchors.verticalCenter: parent.verticalCenter56 anchors.verticalCenter: parent.verticalCenter
56 width: units.gu(2)57 width: units.gu(2)
57 height: width58 height: width
5859
=== modified file 'telegram/app/qml/components/MessagesListItem.qml'
--- telegram/app/qml/components/MessagesListItem.qml 2016-11-01 21:03:10 +0000
+++ telegram/app/qml/components/MessagesListItem.qml 2016-11-14 11:39:33 +0000
@@ -245,6 +245,7 @@
245 245
246 AccountMessageMedia {246 AccountMessageMedia {
247 id: message_media247 id: message_media
248 objectName: "accountMessageMedia"
248 message: message_item.message249 message: message_item.message
249 visible: message_media.hasMedia && !uploading250 visible: message_media.hasMedia && !uploading
250 showStatus: !hasLink251 showStatus: !hasLink
@@ -268,6 +269,7 @@
268269
269 Label {270 Label {
270 id: message_text271 id: message_text
272 objectName: "messageText"
271273
272 anchors {274 anchors {
273 top: parent.top275 top: parent.top
@@ -296,6 +298,7 @@
296298
297 MessageStatus {299 MessageStatus {
298 id: message_status300 id: message_status
301 objectName: "messageStatus"
299 anchors {302 anchors {
300 top: message_text.bottom303 top: message_text.bottom
301 right: parent.right304 right: parent.right
302305
=== modified file 'telegram/app/qml/telegram.qml'
--- telegram/app/qml/telegram.qml 2016-07-19 15:15:28 +0000
+++ telegram/app/qml/telegram.qml 2016-11-14 11:39:33 +0000
@@ -235,6 +235,7 @@
235 }235 }
236236
237 AdaptivePageLayout {237 AdaptivePageLayout {
238 objectName: "APL"
238 id: pageStack239 id: pageStack
239240
240 property bool forceSinglePage: false241 property bool forceSinglePage: false
241242
=== added directory 'telegram/autopilot'
=== added directory 'telegram/autopilot/CLI'
=== added file 'telegram/autopilot/CLI/canonical-logo.png'
242Binary files telegram/autopilot/CLI/canonical-logo.png 1970-01-01 00:00:00 +0000 and telegram/autopilot/CLI/canonical-logo.png 2016-11-14 11:39:33 +0000 differ243Binary files telegram/autopilot/CLI/canonical-logo.png 1970-01-01 00:00:00 +0000 and telegram/autopilot/CLI/canonical-logo.png 2016-11-14 11:39:33 +0000 differ
=== added file 'telegram/autopilot/CLI/test_receive_response.lua'
--- telegram/autopilot/CLI/test_receive_response.lua 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/CLI/test_receive_response.lua 2016-11-14 11:39:33 +0000
@@ -0,0 +1,149 @@
1function on_msg_receive (msg)
2
3 status_online(ok_cb, false);
4
5 -- Uncomment, if debugging, to see all properties of objects
6 -- print ("Message From data...")
7 -- getAllData(msg.from,nil)
8 -- print ("Message To data...")
9 -- getAllData(msg.to,nil)
10 -- print ("Message data...")
11 -- getAllData(msg,nil)
12
13 -- if (msg.media ~= nil) then
14 -- print ("Message Media data...")
15 -- getAllData(msg.media,nil)
16 -- end
17
18 if msg.out then
19 return
20 end
21
22 if (msg.text == nil) and (msg.media == nil) then
23 return
24 end
25
26 if (msg.to.peer_type == "encr_chat") or (msg.to.peer_type == "chat") then
27 from_name = msg.to.print_name;
28 sleep_timer = 2;
29 else
30 from_name = msg.from.print_name;
31 sleep_timer = 3;
32 end
33
34 if (msg.text ~= nil) and string.find(msg.text, "INSTANT") then
35 sleep_timer = 0;
36 end
37
38 if (msg.media ~= nil) then
39 sleep_timer = 3;
40 end
41
42 if (msg.text ~= nil) then
43
44 -- wait for sender to run 'sending' confirmation checks
45 sleep(sleep_timer);
46
47 -- mark the message as read
48 mark_read(from_name, ok_cb, false);
49
50 if string.find(msg.text, "DO NOT REPLY") then
51 return
52 end
53
54 -- generate and send an image response, if asked for
55 if string.find(msg.text, "SEND IMAGE") then
56 image_location = (string.sub( debug.getinfo(1).source, 2, string.len(debug.getinfo(1).source) - 25 ));
57 image_file = "canonical-logo.png";
58 send_photo (from_name, (image_location .. image_file), ok_cb, false);
59 else
60 -- generate and send a text response
61 reply = ("ReplyTo:" .. msg.text);
62 send_msg (from_name, reply, ok_cb, false);
63
64 end
65 end
66
67 if (msg.media ~= nil) then
68
69 -- wait for sender to run 'sending' confirmation checks
70 sleep(sleep_timer);
71
72 mark_read(from_name, ok_cb, false);
73 end
74
75
76end
77
78
79function ok_cb (extra, success, result)
80
81end
82
83
84function on_our_id (id)
85
86end
87
88function on_secret_chat_created (peer)
89
90end
91
92function on_user_update (user)
93
94 -- Change status to online
95 status_online(ok_cb, false);
96
97end
98
99function on_chat_update (user)
100
101 -- Change status to online
102 status_online(ok_cb, false);
103
104end
105
106function on_get_difference_end ()
107
108 -- Change status to online
109 status_online(ok_cb, false);
110
111end
112
113function on_binlog_replay_end ()
114
115 -- Change status to online
116 status_online(ok_cb, false);
117
118end
119
120-- Helper Methods
121
122-- Sleep function to insert a delay in execution
123function sleep(n)
124 os.execute("sleep " .. tonumber(n))
125end
126
127-- Recursive function to obtain properties of an object
128function getAllData(t, prevData)
129 -- if prevData == nil, start empty, otherwise start with prevData
130 local data = prevData or {}
131
132 -- copy all the attributes from t
133 for k,v in pairs(t) do
134 data[k] = data[k] or v
135 print(string.format("Key: %s, Value:%s", k, data[k]))
136 end
137
138
139 -- get t's metatable, or exit if not existing
140 local mt = getmetatable(t)
141 if type(mt)~='table' then return data end
142
143 -- get the __index from mt, or exit if not table
144 local index = mt.__index
145 if type(index)~='table' then return data end
146
147 -- include the data from index into data, recursively, and return
148 return getAllData(index, data)
149end
0150
=== added directory 'telegram/autopilot/telegram'
=== added file 'telegram/autopilot/telegram/__init__.py'
=== added directory 'telegram/autopilot/telegram/common'
=== added file 'telegram/autopilot/telegram/common/__init__.py'
--- telegram/autopilot/telegram/common/__init__.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/common/__init__.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,36 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2
3#
4# Ubuntu System Tests
5# Copyright (C) 2016 Canonical
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21from telegram.common.utils import (
22 clean_dir,
23 delete_file,
24 get_random_string,
25 get_tests_ids_to_run,
26 get_tests_to_run,
27)
28
29
30__all__ = [
31 'clean_dir',
32 'delete_file',
33 'get_random_string',
34 'get_tests_ids_to_run',
35 'get_tests_to_run',
36]
037
=== added file 'telegram/autopilot/telegram/common/config.py'
--- telegram/autopilot/telegram/common/config.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/common/config.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,350 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2
3#
4# Ubuntu System Tests
5# Copyright (C) 2014-2016 Canonical
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import configparser
22import logging
23import os
24
25from telegram.common import options
26
27logger = logging.getLogger(__name__)
28config_stack = None
29
30DEFAULT_CONF = 'ubuntu-system-tests.conf'
31KEY_DEFAULT = 'default'
32
33
34CONFIG_OPTIONS = [
35 options.Option(
36 'device_serial', help_string='Device serial'),
37 options.Option(
38 'device_password', help_string='Device password', mandatory=True),
39 options.Option(
40 'output_dir', mandatory=True,
41 help_string='Directory to store the tests results and artifacts.\n'
42 'WARNING: This directory will have all existing content '
43 'deleted!'),
44 options.Option(
45 'sim_0_pin', mandatory=True,
46 help_string='SIM pin for the card in the first slot'),
47 options.Option(
48 'sim_1_pin',
49 help_string='SIM pin for the card in the second slot'),
50 options.Option(
51 'wifi_ssid', mandatory=True,
52 help_string='Wi-Fi SSID used to connect during setup wizard'),
53 options.Option(
54 'wifi_password', mandatory=True,
55 help_string='Wi-Fi password used to connect during setup wizard'),
56 options.Option(
57 'device_security', default='Passcode',
58 help_string='The security method to select during setup wizard'),
59 options.Option(
60 'bluetooth_device_name',
61 help_string='Name of a nearby bluetooth pairing device'),
62 options.Option(
63 'device_phone_number',
64 help_string="The phone number of the SIM card inserted in the first "
65 "SIM slot. This must be formatted exactly as you would "
66 "dial it."),
67 options.Option(
68 'device_phone_number2',
69 help_string="The phone number of the SIM card inserted in the second "
70 "SIM slot. If the device has only one SIM slot, you can "
71 "leave this blank. This must be formatted exactly as you "
72 "would dial it."),
73 options.Option(
74 'telephony_service_number1',
75 help_string="The phone number to call and message from "
76 "in the telephony service. In Twilio go to "
77 "https://www.twilio.com/user/account/"
78 "phone-numbers/incoming and click on the number "
79 "you want to use, then copy the 'Phone Number' "
80 "field exactly."),
81 options.Option(
82 'telephony_service_number2',
83 help_string="The second phone number to call and message from "
84 "in the telephony service. In Twilio go to "
85 "https://www.twilio.com/user/account/"
86 "phone-numbers/incoming and click on the number "
87 "you want to use, then copy the 'Phone Number' "
88 "field exactly."),
89 options.Option(
90 # this is a private key, that will not be exported to
91 # autopilot directly
92 '_twilio_account_sid', mandatory=True,
93 help_string='Account SID for Twilio. Please log into '
94 'https://www.twilio.com/login '
95 'and select \'Dashboard -> Show API Credentials\'.'
96 'Then copy and paste the Account SID value here.'),
97 options.Option(
98 # this is a private key, that will not be exported to
99 # autopilot directly
100 '_twilio_auth_token', mandatory=True,
101 help_string='Auth token for Twilio account. Please log into '
102 'https://www.twilio.com/login '
103 'and select \'Dashboard -> Show API Credentials\'.'
104 'Then copy and paste the Auth token value here.'),
105 options.Option(
106 # this is a private key, that will not be exported to
107 # autopilot directly
108 'max_unity8_retry_delay', default=30000,
109 help_string='The boundary for how long we should be retrying until '
110 'unity8 is started'),
111 options.Option(
112 'app_startup_cold_runs', default=0,
113 help_string='How many iterations to run for the cold start app '
114 'performance tests?'),
115 options.Option(
116 'app_startup_hot_runs', default=0,
117 help_string='How many iterations to run for the hot start app '
118 'performance tests?'),
119 options.Option(
120 'email_outlook', default='platform_qa_test@outlook.com',
121 help_string='@outlook.com email address to use for email tests'),
122 options.Option(
123 'password_outlook', mandatory=True,
124 help_string='@outlook.com password to use for email tests'),
125 options.Option(
126 'email_yahoo', default='platform_qa_test_account@yahoo.com',
127 help_string='@yahoo.com email address to use for email tests'),
128 options.Option(
129 'password_yahoo', mandatory=True,
130 help_string='@yahoo.com password to use for email tests'),
131 options.Option(
132 'username_imap', default='platform-qa-test-account',
133 help_string='IMAP username to use for email tests'),
134 options.Option(
135 'password_imap', mandatory=True,
136 help_string='IMAP password to use for email tests'),
137 options.Option(
138 'pictures_scalability_runs',
139 help_string='The different loads used for scalability pictures tests '
140 'separated by comma'),
141 options.Option(
142 '_practitest_project_id',
143 help_string='Practitest project ID to use for retrieving test lists.'),
144 options.Option(
145 '_practitest_api_token',
146 help_string='Practitest api token used for authentication.'),
147 options.Option(
148 'country_sim', default='United States',
149 help_string='The name of the country of the SIM card to use for '
150 'telegram login'),
151]
152
153
154def get_user_config_dir():
155 """Return the path to the user configuration directory."""
156 conf_dir = os.environ.get(
157 'XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
158 return conf_dir
159
160
161def get_device_config_file_path():
162 """Return the path of the config file copied to the device."""
163 return '/tmp/ubuntu-system-tests.conf'
164
165
166def get_device_config_section():
167 """Return the name of config section to use."""
168 return os.environ.get('CONFIG_SECTION')
169
170
171def get_config_stack_from_file(file_path, config_section=None):
172 """Return config stack from specified file path."""
173 config = UbuntuSystemTestsConfig(file_path, section=config_section)
174 config.get_config_from_file()
175 return config
176
177
178def get_device_config_stack():
179 """Return the config stack variable"""
180 global config_stack
181 if not config_stack:
182 config_stack = get_config_stack_from_file(
183 get_device_config_file_path(), get_device_config_section())
184 return config_stack
185
186
187def get_test_config_values(config_stack):
188 """ Return a string containing the comma separated key=value options.
189 The list includes the config values and the temporal ones as well
190 """
191 return config_stack.get_autopilot_config_string()
192
193
194class UbuntuSystemTestsConfig():
195
196 """Class to get and save test configuration data."""
197
198 def __init__(self, file_name=None, section=None, options=None):
199 """
200 Construct the config and parser object.
201 :param file_name: Name of config file to load. Default file is used if
202 value is not specified.
203 :param section: Name of section to use in config file. Default section
204 is used if not specified.
205 :param options: List of options that should be specified in config.
206 Default list of options is used if not specified.
207 """
208 user_config_dir = get_user_config_dir()
209 if not os.path.exists(user_config_dir):
210 os.mkdir(user_config_dir)
211 self.file_path = os.path.join(
212 user_config_dir, file_name or DEFAULT_CONF)
213 self.section = section or KEY_DEFAULT
214 self.parser = configparser.ConfigParser(
215 allow_no_value=True, empty_lines_in_values=False,
216 default_section=KEY_DEFAULT)
217 self.config = {}
218 self.options = options or CONFIG_OPTIONS
219
220 def set(self, option_name, value):
221 """Set a config value.
222 :param option_name: Name of config option.
223 :param value: Value to set.
224 """
225 self.config[option_name] = value
226 self.save()
227
228 def get(self, option_name, default=''):
229 """Get a config value.
230 :param option_name: Name of config option to get.
231 :param default: Value to return as default if item doesn't exist.
232 :return: Config option value if it exists. If the config option itself
233 doesn't exist, return None. Otherwise if the option exists but no value
234 is defined return the default value."""
235 return self.config.get(option_name, default)
236
237 def save(self):
238 """Save the config to file."""
239 mode = 'r+' if os.path.exists(self.file_path) else 'w'
240 with open(self.file_path, mode) as f:
241 self.parser.write(f)
242
243 def get_config_from_string(self, string):
244 """Load config from a string. This is used for selftests only.
245 :param string: Config string to load from.
246 """
247 self.parser.read_string(string)
248 self._save_config_for_section()
249
250 def get_config_from_file(self):
251 """Load config from file."""
252 self.parser.read(self.file_path)
253 self._save_config_for_section()
254
255 def _save_config_for_section(self):
256 """Save the current config for the specified section only."""
257 self.config = self.parser[self.section]
258
259 def get_missing_options(self, silent=False):
260 """Check through each required option and get a value for each one
261 that is not present.
262 :param silent: Whether to query stdin for an input value or take a
263 default value where it exists.
264 """
265 save_required = False
266 for option in self.options:
267 if option.name in self.config:
268 # name exists, check if its mandatory and if a value exists
269 if option.mandatory and not self.config.get(option.name):
270 # mandatory and no value exists, so get one
271 self._get_option_value(option, silent)
272 save_required = True
273 else:
274 # option name not in config, get a value
275 self._get_option_value(option, silent)
276 save_required = True
277 self._save_if_required(save_required)
278
279 def _save_if_required(self, save_required):
280 """Save config if it is required.
281 :param save_required: Whether to save or not.
282 """
283 if save_required:
284 self.save()
285
286 def _get_option_value(self, option, silent):
287 """Request a value for specified option.
288 :param option: Required option.
289 :param silent: Whether to query stdin or take default value.
290 """
291 if silent:
292 default = option.default
293 if default:
294 self.config[option.name] = option.default
295 logger.warning(
296 'In silent mode no value specified for option: "{o}". '
297 'Using default value "{v}".'.format(
298 o=option.name, v=default))
299 else:
300 logger.warning(
301 'In silent mode no default value specified for option: '
302 '"{o}". Continuing with value unset.'.format(
303 o=option.name))
304 else:
305 self._get_option_value_from_stdin(option)
306
307 def _get_option_value_from_stdin(self, option):
308 """Request option value from stdin.
309 :param option: Required option.
310 """
311 help_msg = self._get_option_help_text(option)
312 print(help_msg, end='')
313 value = self._get_value_from_user_or_default(option)
314 self.config[option.name] = value
315
316 def _get_option_help_text(self, option):
317 """Return help message for specified option.
318 :param option: Required option.
319 """
320 help_msg = option.help_string
321 default = option.default
322 if default:
323 help_msg += ' (leave blank to use default value: {})'.format(
324 default)
325 elif not option.mandatory:
326 help_msg += ' (leave blank if not required)'
327 help_msg += ': '
328 return help_msg
329
330 def _get_value_from_user_or_default(self, option):
331 """Return value from stdin or default value if no stdin value."""
332 return input() or option.default
333
334 def get_autopilot_config_string(self):
335 """Return the configuration in a string usable by Autopilot.
336
337 That is, a list of key=value pairs serparated by comma.
338
339 Any keys starting with _ will be ignored.
340
341 """
342 config = ''
343 for key, value in self.config.items():
344 if not key.startswith('_'):
345 config += '{k}={v},'.format(k=key, v=value)
346
347 # remove trailing ',' if it exists
348 if config.endswith(','):
349 config = config[:-1]
350 return config
0351
=== added file 'telegram/autopilot/telegram/common/options.py'
--- telegram/autopilot/telegram/common/options.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/common/options.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,37 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2
3#
4# Ubuntu System Tests
5# Copyright (C) 2016 Canonical
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21
22class Option():
23
24 """Class to represent configuration option."""
25
26 def __init__(self, name, help_string, default=None, mandatory=False):
27 """
28 Construct the Option object.
29 :param name: Name of option.
30 :param help_string: Help message to explain option to user.
31 :param default: Default value for option.
32 :param mandatory: Whether the option is mandatory or not.
33 """
34 self.name = name
35 self.help_string = help_string
36 self.default = str(default) if default else None
37 self.mandatory = mandatory
038
=== added file 'telegram/autopilot/telegram/common/ssh.py'
--- telegram/autopilot/telegram/common/ssh.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/common/ssh.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,199 @@
1#!/usr/bin/env python3
2# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3
4#
5# Ubuntu System Tests
6# Copyright (C) 2015 Canonical
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21
22import getpass
23import glob
24import os
25import re
26import socket
27import stat
28import subprocess
29
30from ubuntu_system_tests.common import (
31 get_random_string,
32 delete_file
33)
34
35SSH_IP = 'SSH_IP'
36SSH_PASSPHRASE = 'SSH_PASSPHRASE'
37SSH_PRIVATE_KEY = 'SSH_PRIVATE_KEY'
38SSH_USER = 'SSH_USER'
39
40
41def get_ssh_ip_address():
42 """Return ssh passphrase value."""
43 return os.environ.get(SSH_IP)
44
45
46def get_ssh_passphrase():
47 """Return ssh passphrase value."""
48 return os.environ.get(SSH_PASSPHRASE)
49
50
51def get_ssh_private_key():
52 """Return path to ssh private key file."""
53 return os.environ.get(SSH_PRIVATE_KEY)
54
55
56def get_ssh_user():
57 """Return ssh username value."""
58 return os.environ.get(SSH_USER)
59
60
61def _get_local_ip_address():
62 """ Retrieve the local ip address
63 :return: The ip obtained from the socket connection
64 """
65 ip = '127.0.0.1'
66 try:
67 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
68 s.connect(("8.8.8.8", 80))
69 ip = s.getsockname()[0]
70 finally:
71 s.close()
72 return ip
73
74
75def _get_set_env_var_command(name, value):
76 """Return command to set environment variable on device."""
77 return ['--env={n}={v}'.format(n=name, v=value)]
78
79
80def _get_copy_file_to_device_command(src, dest):
81 """Return command to copy a file to the device."""
82 return ['--copy', '{s}:{d}'.format(s=src, d=dest)]
83
84
85def get_ssh_config_commands():
86 """ Retrieve a private key that can be used to connect to the host and add
87 the public key to the authorized_keys if it is not included yet. If either
88 it is not required to configure ssh or the ssh password is defined,
89 keypairs are not used and the function return None
90 """
91 cmds = []
92 cmds.extend(_get_set_env_var_command(SSH_IP, _get_local_ip_address()))
93 cmds.extend(_get_set_env_var_command(SSH_USER, getpass.getuser()))
94
95 # Add the private key and the passphrase when it is needed
96 private_key = get_valid_key()
97 if not private_key:
98 private_key, public_key = generate_keypair(get_random_string(10))
99 add_public_key_to_ssh_uthorized_keys(public_key)
100 os.remove(public_key)
101
102 device_key_file = get_device_keyfile_path(private_key)
103 cmds.extend(_get_set_env_var_command(
104 SSH_PASSPHRASE, _get_key_passprhase(private_key)))
105 cmds.extend(_get_set_env_var_command(SSH_PRIVATE_KEY, device_key_file))
106 cmds.extend(_get_copy_file_to_device_command(private_key, device_key_file))
107 return cmds
108
109
110def _get_key_passprhase(private_key):
111 """ Get the passphrase from the name, None if it is not found """
112 keyname = os.path.basename(private_key)
113 match = re.search(r'test_(.+)_key', keyname)
114 if match:
115 return match.group(1)
116 else:
117 return
118
119
120def _get_ssh_authorized_keys_path():
121 path = os.path.join(os.path.expanduser('~'), '.ssh', 'authorized_keys')
122 directory = os.path.dirname(path)
123 if not os.path.exists(directory):
124 os.makedirs(directory)
125 if not os.path.exists(path):
126 file = open(path, 'w')
127 file.close()
128 return path
129
130
131def is_authorized_key(id):
132 """ Indicate if the comment it is part of the ssh authorized_keys file
133 :param id: a string used to identify the public key. Currently the
134 passphrase is being used for that
135 """
136 authorized_keys = _get_ssh_authorized_keys_path()
137 command_check = ['grep', '"{c}"'.format(c=id), authorized_keys]
138 return subprocess.call(command_check, stdout=subprocess.PIPE) == 0
139
140
141def add_public_key_to_ssh_uthorized_keys(public_key):
142 """ Add the public key to the ssh authorized_keys if is not included yet"""
143 # In case the public key is not authorized yet, add it to the
144 # authorized_keys file
145 authorized_keys = _get_ssh_authorized_keys_path()
146 command_add = 'cat {public_key} >> {authorized_keys}'.format(
147 public_key=public_key, authorized_keys=authorized_keys)
148 subprocess.call(command_add, shell=True)
149
150
151def get_valid_key():
152 """ Retrieve a private key which has its public key is already authorized
153 to be used through ssh
154 """
155 all_keys = get_all_defined_keys()
156 for key in all_keys:
157 passphrase = _get_key_passprhase(key)
158 if passphrase and is_authorized_key(passphrase):
159 return key
160 return
161
162
163def get_all_defined_keys():
164 """ Retrieve the keys already saved in the tmp dir """
165 return glob.glob('/tmp/test_*_key')
166
167
168def generate_keypair(passphrase):
169 """ Create a pair of keys with the passphrase as part of the key names """
170 keypath = '/tmp/test_{}_key'.format(passphrase)
171 command = 'ssh-keygen -t rsa -b 4096 -C "{p}" -P "{p}" -f {k} -q'
172 command = command.format(p=passphrase,
173 k=keypath)
174 subprocess.check_call(command, shell=True)
175 return keypath, keypath + '.pub'
176
177
178def get_device_keyfile_path(filepath):
179 """Return the path of the config file copied to the device."""
180 return os.path.join('/tmp', os.path.basename(filepath))
181
182
183def prepare_device_keys():
184 """ Prepare the keyfile to be used by changing the ownership and the
185 permissions. These changes are done when other ssh authentication
186 mechanisms have not being selected
187 """
188 passphrase = get_ssh_passphrase()
189 key_file = get_ssh_private_key()
190
191 if passphrase and key_file and os.path.isfile(key_file):
192 os.chown(key_file, os.getuid(), os.getgid())
193 os.chmod(key_file, stat.S_IREAD)
194
195
196def ensure_device_keyfile_deleted():
197 """ Delete the private key file in the device when required """
198 key_file = get_ssh_private_key()
199 not key_file or delete_file(key_file)
0200
=== added file 'telegram/autopilot/telegram/common/utils.py'
--- telegram/autopilot/telegram/common/utils.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/common/utils.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,87 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2
3#
4# Ubuntu System Tests
5# Copyright (C) 2015 Canonical
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import inspect
22import os
23import random
24import shutil
25import string
26
27
28def clean_dir(dir_path):
29 """Delete all the content of the directory"""
30 if os.path.isdir(dir_path):
31 for obj in os.listdir(dir_path):
32 _delete(os.path.join(dir_path, obj))
33
34
35def _delete(obj):
36 """ Delete an object which could be either a file or a dir """
37 if os.path.isfile(obj):
38 os.remove(obj)
39 else:
40 shutil.rmtree(obj, True)
41
42
43def delete_file(file_name):
44 """Delete the file passed as parameter. In case the file does not
45 exist, the deletion is skipped"""
46 if os.path.isfile(file_name):
47 os.unlink(file_name)
48
49
50def get_random_string(length=10):
51 """Get a string with random content"""
52 return ''.join(random.choice(string.ascii_uppercase) for i in
53 range(length))
54
55
56def get_tests_ids_to_run(tests_module=None, testsuite_list_filepath=None):
57 """Return a list of the test ids to run in the test bed.
58
59 :param tests_module: The module that contains the Ubuntu System Tests.
60 Default value is ubuntu_system_tests.tests. Currently, a value other
61 than the default is used only for self-testing.
62
63 """
64 tests_from_config = get_tests_to_run()
65 if tests_from_config:
66 return tests_from_config.split()
67
68 # If we do this at the module level then we need to have unity8 and UITK on
69 # the host and would rather avoid this
70 from ubuntu_system_tests import external_tests
71 test_ids = external_tests.get_external_test_ids(testsuite_list_filepath)
72
73 if tests_module is None:
74 # We delay the import so this is only executed in the test bed, not on
75 # the host which might have a different version of the libraries used
76 # in the system tests.
77 from ubuntu_system_tests import tests
78 tests_module = tests
79
80 if inspect.ismodule(tests_module):
81 test_ids.append(tests_module.__name__)
82
83 return test_ids
84
85
86def get_tests_to_run():
87 return os.getenv('TESTS_TO_RUN')
088
=== added file 'telegram/autopilot/telegram/emulators.py'
--- telegram/autopilot/telegram/emulators.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/emulators.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,550 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2# Copyright 2016 Canonical
3#
4# This file is part of telegram-app.
5#
6# telegram-app is free software: you can redistribute it and/or modify it
7# under the terms of the GNU General Public License version 3, as published
8# by the Free Software Foundation.
9
10
11"""Telegram app autopilot emulators."""
12
13from autopilot import logging as autopilot_logging
14from autopilot.introspection.dbus import StateNotFoundError
15from autopilot.utilities import sleep
16from autopilot import platform
17
18from ubuntuuitoolkit import emulators as toolkit_emulators
19from ubuntuuitoolkit._custom_proxy_objects import _common
20from ubuntuuitoolkit._custom_proxy_objects._common import is_maliit_process_running
21#from ubuntu_keyboard.emulators.keyboard import Keyboard as UbuntuKeyboard
22#from address_book_app import address_book
23
24from telegram import utilities
25
26import logging
27import time
28import dbus
29
30# from telegram.helpers.notifications.utils import Notifications
31
32
33#logger = logging.getLogger(__name__)
34class MainView(toolkit_emulators.MainView):
35
36 def __init__(self, *args):
37 super(MainView, self).__init__(*args)
38 self.pointing_device = toolkit_emulators.get_pointing_device()
39 self._account_page = None
40 self._apl = None
41 self._content_hub_popup = None
42 self._content_picker = None
43 self._content_hub_app_gallery = None
44 self._confirmation_dialog = None
45
46 @property
47 def account_page(self):
48 if self._account_page is None:
49 try:
50 self._account_page = self.wait_select_single(AccountPage, objectName="accountPage", active=True)
51 except StateNotFoundError:
52 raise RuntimeError("User needs to be logged on")
53 return self._account_page
54
55 @property
56 def apl(self):
57 if self._apl is None:
58 self._apl = self.wait_select_single(AdaptivePageLayout, objectName="APL", active=True)
59 return self._apl
60
61 @property
62 def content_picker(self):
63 if self._content_hub_popup is None:
64 self._content_hub_popup = self.wait_select_single(objectName="mediaImportPopup")
65 self._content_picker = self._content_hub_popup.wait_select_single(objectName="contentPeerPicker")
66 return self._content_picker
67
68 def select_content_hub_app(self, appName):
69 cp = self.content_picker
70 content_hub_gridviews = cp.select_many(objectName="responsiveGridViewGrid")
71 for gridview in content_hub_gridviews:
72 app_icon_labels = gridview.select_many(objectName="label")
73 if len(app_icon_labels) > 0:
74 for app_icon_label in app_icon_labels:
75 if appName in app_icon_label.text:
76 self.pointing_device.click_object(app_icon_label)
77 return
78
79 @property
80 def confirmation_dialog(self):
81 if self._confirmation_dialog is None:
82 self._confirmation_dialog = self.wait_select_single(Dialog, objectName='confirmationDialog')
83 return self._confirmation_dialog
84
85 def click_header_action(self, action):
86 """Click the action 'action' on the header"""
87 action = self.wait_select_single(objectName='%s_button' % action)
88 self.pointing_device.click_object(action)
89
90 # def get_notifications_list(self):
91 # """Return a list of notifications currently being displayed."""
92 # return self.wait_select_single(Notifications, objectName='notificationList')
93
94
95class AdaptivePageLayout(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
96
97 def __init__(self, *args):
98 super(AdaptivePageLayout, self).__init__(*args)
99 self._intro_page = None
100 self._contacts_page = None
101 self._dialog_page = None
102 self._settings_page = None
103 self._profile_page = None
104 self._countries_page = None
105 self._auth_phone_page = None
106 self._auth_code_page = None
107
108 @property
109 def intro_page(self):
110 if self._intro_page is None:
111 try:
112 self._intro_page = self.wait_select_single(IntroPage, objectName='introPage', active=True)
113 except StateNotFoundError:
114 raise RuntimeError("Intro page is not active")
115 return self._intro_page
116
117 @property
118 def countries_page(self):
119 if self._countries_page is None:
120 self._countries_page = self.wait_select_single(AuthCountriesPage, objectName='countriesListPage', active=True)
121 return self._countries_page
122
123 @property
124 def auth_phone_page(self):
125 if self._auth_phone_page is None:
126 self._auth_phone_page = self.wait_select_single(AuthNumberPage, objectName='authPhonePage', active=True)
127 return self._auth_phone_page
128
129 @property
130 def auth_code_page(self):
131 if self._auth_code_page is None:
132 self._auth_code_page = self.wait_select_single(AuthCodePage, objectName='authCodePage', active=True)
133 return self._auth_code_page
134
135 @property
136 def contacts_page(self):
137 if self._contacts_page is None:
138 self._contacts_page = self.wait_select_single(AccountContactsPage, objectName='accountContactsPage', active=True)
139 return self._contacts_page
140
141 @property
142 def dialog_page(self):
143 if self._dialog_page is None:
144 self._dialog_page = self.wait_select_single(AccountDialogPage, objectName='dialogPage', active=True)
145 return self._dialog_page
146
147 @property
148 def settings_page(self):
149 if self._settings_page is None:
150 self._settings_page = self.wait_select_single(AccountSettings, objectName="settingsPage", active=True)
151 return self._settings_page
152
153 @property
154 def profile_page(self):
155 if self._profile_page is None:
156 self._profile_page = self.wait_select_single(ProfilePage, objectName="profilePage", active=True)
157 return self._profile_page
158
159 def clear_profile_page(self):
160 self._profile_page = None
161
162
163class IntroPage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
164 def __init__(self, *args):
165 super(IntroPage, self).__init__(*args)
166
167 def press_start_messaging(self):
168 return self.pointing_device.click_object(self.wait_select_single(objectName="startMessagingButton"))
169
170class AccountPage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
171
172 def open_account_panel(self):
173 self.click_action_button('navigationMenu')
174 account_panel = self.wait_select_single(AccountPanel, objectName='accountPanel')
175 account_panel.visible.wait_for(True)
176 return account_panel
177
178 def get_mainview_header(self):
179 """Return the Header custom proxy object of the Page."""
180 return self.get_root_instance().wait_select_single('MainView').get_header()
181
182 def get_default_header(self):
183 try:
184 return self.wait_select_single('PageHeader', objectName='defaultHeader')
185 except:
186 raise RuntimeError('The Account Page has no header.')
187
188 def click_action_button(self, action_name):
189 action = self.wait_select_single(objectName='%s_button' % action_name)
190 self.pointing_device.click_object(action)
191
192 def get_dialog_list_page(self):
193 return self.wait_select_single(AccountDialogList, objectName='accountDialogList')
194
195
196class AccountPanel(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
197
198 def get_account_panel_list(self):
199 return self.wait_select_single('AccountPanel', objectName='accountPanel')
200
201 def get_account_panel_count(self):
202 return self.get_account_panel_list().count
203
204 def get_account_panel_delegate(self, index):
205 return self.wait_select_single('AccountPanelItem', objectName='contact{}'.format(index))
206
207 def select_secret_chat(self):
208 action = self.wait_select_single('AccountPanelItem', objectName='secretChatItem')
209 self.pointing_device.click_object(action)
210
211 def select_group_chat(self):
212 action = self.wait_select_single('AccountPanelItem', objectName='groupChatItem')
213 self.pointing_device.click_object(action)
214
215 def select_contacts(self):
216 action = self.wait_select_single('AccountPanelItem', objectName='panelContacts')
217 self.pointing_device.click_object(action)
218
219 def select_settings(self):
220 action = self.wait_select_single('AccountPanelItem', objectName='panelSettings')
221 self.pointing_device.click_object(action)
222
223
224class AccountContactsPage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
225
226 def __init__(self, *args):
227 super(AccountContactsPage, self).__init__(*args)
228 self._index_of_first_online_contact = None
229
230
231 def _get_contacts_list(self):
232 return self.wait_select_single('MultipleSelectionListView', objectName='contactList')
233
234 def _get_contacts_count(self):
235 return self._get_contacts_list().count
236
237 def _get_contact_delegate(self, index):
238 return self.wait_select_single(
239 'TelegramContactsListItem', objectName='contact{}'.format(index))
240
241 def _click_action_button(self, action_name):
242 action = self.wait_select_single(objectName='%s_button' % action_name)
243 if (action):
244 self.pointing_device.click_object(action)
245 else:
246 raise StateNotFoundError(action_name)
247
248
249 def select_first_online_contact(self):
250 #Select first contact if online (User MUST be online)
251 delegate = None
252 for index in range(self._get_contacts_count()):
253 delegate = self._get_contact_delegate(index)
254 if (delegate.isOnline):
255 self._index_of_first_online_contact = index
256 break
257
258 if delegate != None:
259 return delegate
260 else:
261 raise RuntimeError('Chat cannot be created. There are no online users')
262
263 def select_second_contact(self):
264 if self._index_of_first_online_contact is None:
265 raise RuntimeError('Please select first online contact before selecting a second contact')
266
267 #Select a second contact
268 delegate = None
269 for index in range(self._get_contacts_count()):
270 if index is not self._index_of_first_online_contact:
271 delegate = self._get_contact_delegate(index)
272 break
273
274 if delegate != None:
275 return delegate
276 else:
277 raise RuntimeError('Chat cannot be created. Cannot select second contact')
278
279 def select_contact_at_index(self, index):
280 delegate = self._get_contact_delegate(index)
281 return delegate
282
283 def enter_group_chat_title(self, title):
284 text_field = self.wait_select_single('TextField', objectName='groupChatTextField')
285 utilities.enter_text_in_text_area(text_field, title)
286 self._click_action_button("createGroupChatOK")
287
288
289class AccountDialogList(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
290
291 @property
292 def dialog_count(self):
293 return self._get_dialog_list().count
294
295 def select_dialog_at_index(self, index):
296 selected_dialog = self._get_dialog_delegate(index)
297 self.pointing_device.click_object(selected_dialog)
298
299 def select_new_secret_chat(self):
300 count = self.dialog_count
301 count_including_new_secret_chat = count + 1
302 while (count != count_including_new_secret_chat):
303 count = self.dialog_count
304 self.select_first_dialog()
305
306 def _get_dialog_list(self):
307 return self.wait_select_single(objectName='dialogListView')
308
309 def _get_dialog_delegate(self, index):
310 return self.wait_select_single(
311 'DialogsListItem', objectName='dialog{}'.format(index))
312
313
314class AccountDialogPage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
315
316 def __init__(self, *args):
317 super(AccountDialogPage, self).__init__(*args)
318 self._account_message_list = None
319 self._message_area = None
320
321 @property
322 def account_message_list(self):
323 if self._account_message_list is None:
324 self._account_message_list = self.wait_select_single(AccountMessageList, objectName="accountMessageList")
325 return self._account_message_list
326
327 @property
328 def message_area(self):
329 if self._message_area is None:
330 self._message_area = self.wait_select_single(AccountSendMessage, objectName='accountSendMessageArea')
331 return self._message_area
332
333 def enter_message(self, message):
334 text_area = self.message_area.select_text_area()
335 utilities.enter_text_in_text_area(text_area, message)
336
337 def _get_sending_message_area(self):
338 return self.wait_select_single(AccountSendMessage, objectName='accountSendMessageArea')
339
340 def select_chat_info(self):
341 self.pointing_device.click_object(self.wait_select_single(objectName='groupInfo_button'))
342
343class AccountMessageList(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
344
345 def __init__(self, *args):
346 super(AccountMessageList, self).__init__(*args)
347 self._messages = None
348
349 @property
350 def messages(self):
351 if self._messages is None:
352 self._messages = self.wait_select_single('MultipleSelectionListView', objectName="messagesListView")
353 return self._messages
354
355 def get_message_at_index(self, index):
356 return self.wait_select_single(
357 MessagesListItem, objectName='message{}'.format(index))
358
359
360class AccountSendMessage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
361
362 def select_text_area(self):
363 return(self.wait_select_single('TextArea', objectName='sendMessageTextArea'))
364
365 def select_attach_or_send(self):
366 self.pointing_device.click_object(self.wait_select_single(objectName='sendMouseArea'))
367
368 def select_attach_sticker_option(self):
369 self.pointing_device.click_object(self.wait_select_single(objectName='stickerButton'))
370
371 def select_attach_photo_option(self):
372 self.pointing_device.click_object(self.wait_select_single(objectName="panelPhoto"))
373
374 def select_attach_video_option(self):
375 self.pointing_device.click_object(self.wait_select_single(objectName="panelVideo"))
376
377
378class MessagesListItem(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
379
380 def __init__(self, *args):
381 super(MessagesListItem, self).__init__(*args)
382 self._message_status = None
383 self._message_status_image = None
384 self._message_label = None
385 self._account_message_media = None
386
387 @property
388 def message_status(self):
389 self._message_status = self.wait_select_single(objectName="messageStatus")
390 return self._message_status
391
392 @property
393 def message_status_image(self):
394 self._message_status_image = self.message_status.wait_select_single(objectName="statusImage")
395 return self._message_status_image
396
397 @property
398 def message_label(self):
399 self._message_label = self.wait_select_single(objectName="messageText")
400 return self._message_label
401
402 @property
403 def account_message_media(self):
404 self._account_message_media = self.wait_select_single(AccountMessageMedia, objectName="accountMessageMedia")
405 return self._account_message_media
406
407
408class AccountMessageMedia(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
409
410 def __init__(self, *args):
411 super(AccountMessageMedia, self).__init__(*args)
412 self._media_message_status = None
413 self._media_message_status_image = None
414
415 @property
416 def media_message_status(self):
417 self._media_message_status = self.wait_select_single(objectName="mediaMessageStatus")
418 return self._media_message_status
419
420 @property
421 def media_message_status_image(self):
422 self._media_message_status_image = self.media_message_status.wait_select_single(objectName="statusImage")
423 return self._media_message_status_image
424
425
426class AccountSettings(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
427
428 def __init__(self, *args):
429 super(AccountSettings, self).__init__(*args)
430 self._list_item_logout = None
431 self._settings_list = None
432 self._popup_logout = None
433
434 @property
435 def settings_list(self):
436 if self._settings_list is None:
437 self._settings_list = self.wait_select_single(objectName='settingsList')
438 return self._settings_list
439
440 @property
441 def list_item_logout(self):
442 if self._list_item_logout is None:
443 self._list_item_logout = self.wait_select_single(objectName="listItem_logout")
444 return self._list_item_logout
445
446 def select_list_item_logout(self):
447 self.settings_list.swipe_to_bottom()
448 self.pointing_device.click_object(self.list_item_logout)
449
450
451class ProfilePage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
452
453 def __init__(self, *args):
454 super(ProfilePage, self).__init__(*args)
455
456 @property
457 def _member_list_count(self):
458 return self._get_member_list().count
459
460 def _get_member_list(self):
461 return self.wait_select_single(objectName='memberListView')
462
463 def _get_member_delegate(self, index):
464 return self.wait_select_single(
465 'TelegramContactsListItem', objectName='dialog{}'.format(index))
466
467 def profile_member_at_index(self,index):
468 return self._get_member_delegate(index)
469
470 @property
471 def profile_user_name(self):
472 return self.wait_select_single(objectName="profileUserName")
473
474 @property
475 def profile_user_phone_number(self):
476 return self.wait_select_single(objectName="profilePhoneNumber")
477
478 @property
479 def profile_user_photo(self):
480 return self.wait_select_single(objectName="profileImageImport")
481
482 def select_user_photo(self):
483 return self.wait_select_single(objectName="profileImage")
484
485 @property
486 def switch_block(self):
487 return self.wait_select_single(objectName="switchBlock")
488
489 def select_switch_block(self):
490 self.pointing_device.click_object(self.wait_select_single(objectName="switchBlock"))
491
492 def select_switch_notification(self):
493 self.pointing_device.click_object(self.wait_select_single(objectName="switchNotification"))
494
495 def select_back_button(self):
496 # if platform.model() == "Desktop":
497 # action = self.wait_select_single(objectName='apl_back_action_button')
498 # else:
499 action = self.wait_select_single(objectName='profileBack_button')
500 self.pointing_device.click_object(action)
501
502class AuthCountriesPage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
503
504 def __init__(self, *args):
505 super(AuthCountriesPage, self).__init__(*args)
506
507 def _click_action_button(self, action_name):
508 action = self.wait_select_single(objectName='%s_button' % action_name)
509 try:
510 self.pointing_device.click_object(action)
511 except:
512 raise StateNotFoundError(action_name)
513
514 def profile_member_at_index(self,index):
515 return self._get_member_delegate(index)
516
517 def enter_country_title_and_select(self, title):
518 # Select search icon
519 self._click_action_button("searchIcon")
520 # Type for country
521 text_field = self.wait_select_single('TextField', objectName='countryField')
522 utilities.enter_text_in_text_area(text_field, title)
523 # Select the search country
524 self.pointing_device.click_object(self.wait_select_single(objectName="united_kingdom"))
525
526class AuthNumberPage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
527
528 def __init__(self, *args):
529 super(AuthNumberPage, self).__init__(*args)
530
531 def enter_phone_number(self, title):
532 # Enter text
533 text_field = self.wait_select_single('TextField', objectName='phoneNumberEntry')
534 utilities.enter_text_in_text_area(text_field, title)
535 # Press Send Code button
536 self.pointing_device.click_object(self.wait_select_single(objectName="doneButton"))
537
538class AuthCodePage(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
539
540 def __init__(self, *args):
541 super(AuthCodePage, self).__init__(*args)
542
543 def enter_code_in_textfield(self, title):
544 # Enter text
545 text_field = self.wait_select_single('TextField', objectName='verificationCodeEntry')
546 utilities.enter_text_in_text_area(text_field, title)
547
548 def press_sign_in_button(self):
549 # Press 'Sign In' button
550 self.pointing_device.click_object(self.wait_select_single(objectName="signInButton"))
0\ No newline at end of file551\ No newline at end of file
1552
=== added file 'telegram/autopilot/telegram/setup.py'
--- telegram/autopilot/telegram/setup.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/setup.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,57 @@
1#!/usr/bin/env python3
2
3#
4# Ubuntu System Tests
5# Copyright (C) 2014 Canonical
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import sys
22from setuptools import find_packages, setup
23
24assert sys.version_info >= (3,), 'Python 3 is required'
25
26
27VERSION = '1.0'
28
29
30setup(
31 name='ubuntu-system-tests',
32 version=VERSION,
33 description='Automated tests for Ubuntu Touch images.',
34 author='Canonical Platform QA Team',
35 author_email='qa-team@lists.canonical.com',
36 url='https://launchpad.net/ubuntu-system-tests',
37 license='GPLv3',
38 packages=find_packages(),
39 package_data={
40 'ubuntu_system_tests': ['tests/data/*/*']
41 },
42 install_requires=[
43 'chardet',
44 'python-debian',
45 'requests',
46 'retrying',
47 ],
48 entry_points={
49 'console_scripts': [
50 'ubuntu-system-tests = ubuntu_system_tests.run:main'
51 ]
52 },
53 test_suite='ubuntu_system_tests.selftests',
54 tests_require=[
55 'python-subunit',
56 ]
57)
058
=== added directory 'telegram/autopilot/telegram/tests'
=== added file 'telegram/autopilot/telegram/tests/__init__.py'
--- telegram/autopilot/telegram/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/tests/__init__.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,76 @@
1from autopilot.testcase import AutopilotTestCase
2from autopilot import platform
3from ubuntuuitoolkit import emulators as toolkit_emulators
4from autopilot.input import Mouse, Touch, Pointer
5from telegram import emulators
6from os.path import abspath, dirname, join
7from autopilot.matchers import Eventually
8from testtools.matchers import Equals
9
10import fixtures
11import ubuntuuitoolkit
12import subprocess
13
14class TelegramAppTestCase(AutopilotTestCase):
15
16 def __init__(self, *args):
17 super(TelegramAppTestCase, self).__init__(*args)
18 self._main_view = None
19
20 @property
21 def main_view(self):
22 if self._main_view is None:
23 self._main_view = self.app.wait_select_single(emulators.MainView)
24 return self._main_view
25
26 def setUp(self, parameter=""):
27 #self.pointing_device = Pointer(self.input_device_class.create())
28 super(TelegramAppTestCase, self).setUp()
29
30 subprocess.call(['pkill', 'telegram-app'])
31
32 #Preconditions: Logged In
33 if platform.model() == "Desktop":
34 self.app = self.launch_desktop_application(parameter)
35 else:
36 self.app = self.launch_mobile_application(parameter)
37 self.assertThat(self.main_view.visible, Eventually(Equals(True)))
38 # self.check_user_has_logged_in()
39
40 # if (self.check_user_has_logged_in()):
41 # self.assertThat(self.main_view.visible, Eventually(Equals(True)))
42 # else:
43 # raise RuntimeError("User must be logged in")
44
45
46 def launch_desktop_application(self, parameter):
47 #Setup the lib path environment variable using absolute path values, required by the app to access the necessary libs
48 library_path = abspath(join(dirname(__file__), '..', '..', '..', '..', 'build_desktop',))
49 envValue = library_path + ':$LD_LIBRARY_PATH'
50 self.useFixture(fixtures.EnvironmentVariable('LD_LIBRARY_PATH',envValue))
51
52 #Launch the test application using absolute path values
53 full_path = abspath(join(dirname(__file__), '..', '..', '..', '..', 'build_desktop','lib','x86_64-linux-gnu','bin','telegram'))
54 print(full_path + " " + parameter)
55 return self.launch_test_application(
56 full_path,
57 parameter,
58 app_type='qt',
59 emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
60
61 def launch_mobile_application(self, parameter):
62 return self.launch_click_package(
63 "com.ubuntu.telegram",
64 app_uris=['QT_LOAD_TESTABILITY=1'],
65 emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
66
67 def check_user_has_logged_in(self):
68 account_page = self.main_view.account_page
69 self.assertThat(account_page.visible, Eventually(Equals(True)))
70
71 # try:
72 # self.main_view.get_account_page()
73 # self.assertThat(self.main_view.account_page.visible, Eventually(Equals(True)))
74 # return True
75 # except:
76 # return False
0\ No newline at end of file77\ No newline at end of file
178
=== added file 'telegram/autopilot/telegram/tests/test_Logout.py'
--- telegram/autopilot/telegram/tests/test_Logout.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/tests/test_Logout.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,52 @@
1from telegram.tests import TelegramAppTestCase
2from telegram import emulators
3
4import os
5import dbus
6import time
7import datetime
8import ubuntuuitoolkit
9
10from autopilot.matchers import Eventually
11from testtools.matchers import Equals
12from autopilot.utilities import sleep
13
14
15#from autopilot import logging as autopilot_logging
16#from telegram import displays_and_interactions as interactions
17
18
19class BaseTelegramTestCase(TelegramAppTestCase):
20
21 def setUp(self):
22 super(BaseTelegramTestCase, self).setUp()
23
24
25class Logout(BaseTelegramTestCase):
26
27 # Prerequisites:
28 # - User is already logged on
29 # - User has one contact which is online
30 # - Online contact is running on Telegram CLI
31
32
33 def test_UserLogout(self):
34
35 # Open the account panel by tapping the navigation menu icon
36 account_page = self.main_view.account_page
37 account_panel = account_page.open_account_panel()
38 self.assertThat(account_panel.opened, Eventually(Equals(True)))
39
40 # Select the Settings option
41 account_panel.select_settings()
42
43 # Scroll to select the logout list item
44 apl = self.main_view.apl
45 settings_page = apl.settings_page
46 settings_page.select_list_item_logout()
47 sleep(3)
48 logout_confirm_dialog = self.app.wait_select_single(objectName='logoutDialog')
49 self.main_view.pointing_device.click_object(logout_confirm_dialog.wait_select_single(objectName='logoutConfirm'))
50
51 # Checks that the Intro Page is now active
52 introPage = apl.intro_page
053
=== added file 'telegram/autopilot/telegram/tests/test_MessageDisplay.py'
--- telegram/autopilot/telegram/tests/test_MessageDisplay.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/tests/test_MessageDisplay.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,205 @@
1from telegram.tests import TelegramAppTestCase
2from telegram import emulators
3from telegram import utilities
4
5import os
6import dbus
7import time
8import datetime
9# import subprocess
10import ubuntuuitoolkit
11
12from autopilot.matchers import Eventually
13from testtools.matchers import Equals
14from autopilot.display import Display
15from autopilot import platform
16from autopilot.utilities import sleep
17
18#from autopilot import logging as autopilot_logging
19#from telegram import displays_and_interactions as interactions
20
21messageTypeText = "Autopilot: Text DO NOT REPLY"
22messageTypeSpecialChar = "Autopilot: !$%^&*""()-_''=+?; DO NOT REPLY"
23messageTypeUrl = "http://google.co.uk DO NOT REPLY"
24
25message_status_received = "qrc:/qml/files/check_single_green.png"
26message_status_read = "qrc:/qml/files/check_double_green.png"
27
28class BaseTelegramTestCase(TelegramAppTestCase):
29
30 def setUp(self):
31 super(BaseTelegramTestCase, self).setUp()
32
33class SecretChatTests(BaseTelegramTestCase):
34
35 scenarios = [
36 ('dialog_msgText', {'input': "dialog_msgText"}),
37 ('dialog_msgSpecialChar', {'input': "dialog_msgSpecialChar"}),
38 ('dialog_msgUrl', {'input': "dialog_msgUrl"}),
39 ]
40
41 def test_create_secret_chat(self):
42 # Open the account panel by tapping the navigation menu icon
43 account_page = self.main_view.account_page
44 account_panel = account_page.open_account_panel()
45 self.assertThat(account_panel.opened, Eventually(Equals(True)))
46
47 # Select the secret chat option
48 account_panel.select_secret_chat()
49
50 contact_page = self.main_view.apl.contacts_page
51
52 # PAZ always select online user - Done
53 # Select first contact
54 self.main_view.pointing_device.click_object(contact_page.select_first_online_contact())
55
56 dialog_list_page = account_page.get_dialog_list_page()
57 # Give chance for app to add the secret chat to top of chat list
58 sleep(3)
59 # Select the top chat
60 dialog_list_page.select_dialog_at_index(0)
61
62 dialog_page = self.main_view.apl.dialog_page
63 message_list = dialog_page.account_message_list
64 inital_count = message_list.messages.count
65
66 if self.input == "dialog_msgSpecialChar":
67 dialog_page.enter_message(messageTypeSpecialChar)
68 dialog_page.message_area.select_attach_or_send()
69
70 elif self.input == "dialog_msgUrl":
71 dialog_page.enter_message(messageTypeUrl)
72 dialog_page.message_area.select_attach_or_send()
73
74 elif self.input == "dialog_msgText":
75 dialog_page.enter_message(messageTypeText)
76 dialog_page.message_area.select_attach_or_send()
77
78 # Wait for the message to be sent and allow for network latency
79 # Check that the single tick image is displayed for the sent message
80 sleep(2)
81
82 message = message_list.get_message_at_index(0)
83 self.assertThat(message.message_status_image.source, Eventually(Equals(message_status_received)))
84
85 # Check that the double tick image is displayed for the read message
86 self.assertThat(message.message_status_image.source, Eventually(Equals(message_status_read)))
87
88 # PAZ I believe you need to tap on the URL to make sure it opens up in a browser. Not just
89 # check that the URL received is the same as the URL sent
90
91 # ASH - I don't believe theres a way to determine that Browser app opens up from taping
92 # a link. Could be wrong but some help on this would be appreciated.
93
94 # ASH - Hold off. Needs to be rethinked
95
96 # if self.input == "dialog_msgUrl":
97 # #Click on link
98 # self.main_view.pointing_device.click_object(message.message_label)
99 # #Check hovered link is same as entered link
100 # self.assertThat(message.message_label.hoveredLink, Eventually(Equals(messageTypeUrl)))
101
102 #PAZ - always need to check for double tick
103
104class GroupChatTests(BaseTelegramTestCase):
105
106 scenarios = [
107 ('dialog_msgText', {'input': "dialog_msgText"}),
108 ('dialog_msgSpecialChar', {'input': "dialog_msgSpecialChar"}),
109 ('dialog_msgUrl', {'input': "dialog_msgUrl"}),
110 ]
111
112 def test_create_group_chat(self):
113 # Open the account panel by tapping the navigation menu icon
114 account_page = self.main_view.account_page
115 account_panel = account_page.open_account_panel()
116 self.assertThat(account_panel.opened, Eventually(Equals(True)))
117
118 # Select the secret chat option
119 account_panel.select_group_chat()
120 contact_page = self.main_view.apl.contacts_page
121
122 # Select first contact
123 self.main_view.pointing_device.click_object(contact_page.select_first_online_contact())
124 # Select second contact
125 self.main_view.pointing_device.click_object(contact_page.select_second_contact())
126
127 contact_page.enter_group_chat_title('NewGroupTitle')
128
129 dialog_list_page = account_page.get_dialog_list_page()
130 # Give chance for app to add the group chat to top of chat list
131 sleep(3)
132 # Select the top chat
133 dialog_list_page.select_dialog_at_index(0)
134
135 dialog_page = self.main_view.apl.dialog_page
136 message_list = dialog_page.account_message_list
137 inital_count = message_list.messages.count
138
139 if self.input == "dialog_msgSpecialChar":
140 dialog_page.enter_message(messageTypeSpecialChar)
141 dialog_page.message_area.select_attach_or_send()
142
143 elif self.input == "dialog_msgUrl":
144 dialog_page.enter_message(messageTypeUrl)
145 dialog_page.message_area.select_attach_or_send()
146
147 elif self.input == "dialog_msgText":
148 dialog_page.enter_message(messageTypeText)
149 dialog_page.message_area.select_attach_or_send()
150
151 # Wait for the message to be sent and allow for network latency
152 # Check that the single tick image is displayed for the sent message
153 sleep(1)
154
155 message = message_list.get_message_at_index(0)
156 self.assertThat(message.message_status_image.source, Eventually(Equals(message_status_received)))
157
158 # Check that the double tick image is displayed for the read message
159 self.assertThat(message.message_status_image.source, Eventually(Equals(message_status_read)))
160
161class BasicMessagingTests(BaseTelegramTestCase):
162
163 scenarios = [
164 ('dialog_msgText', {'input': "dialog_msgText"}),
165 ('dialog_msgSpecialChar', {'input': "dialog_msgSpecialChar"}),
166 ('dialog_msgUrl', {'input': "dialog_msgUrl"}),
167 ]
168
169 def test_create_basic_chat(self):
170 # Open the account panel by tapping the navigation menu icon
171 account_page = self.main_view.account_page
172 account_panel = account_page.open_account_panel()
173 self.assertThat(account_panel.opened, Eventually(Equals(True)))
174
175 # Select Contacts option
176 account_panel.select_contacts()
177
178 #Select first contact
179 contact_page = self.main_view.apl.contacts_page
180 self.main_view.pointing_device.click_object(contact_page.select_first_online_contact())
181
182 dialog_page = self.main_view.apl.dialog_page
183 message_list = dialog_page.account_message_list
184 inital_count = message_list.messages.count
185
186 if self.input == "dialog_msgSpecialChar":
187 dialog_page.enter_message(messageTypeSpecialChar)
188 dialog_page.message_area.select_attach_or_send()
189
190 elif self.input == "dialog_msgUrl":
191 dialog_page.enter_message(messageTypeUrl)
192 dialog_page.message_area.select_attach_or_send()
193
194 elif self.input == "dialog_msgText":
195 dialog_page.enter_message(messageTypeText)
196 dialog_page.message_area.select_attach_or_send()
197
198 # Check that the single tick image is displayed for the sent message
199 sleep(1)
200
201 message = message_list.get_message_at_index(0)
202 self.assertThat(message.message_status_image.source, Eventually(Equals(message_status_received)))
203
204 # Check that the double tick image is displayed for the read message
205 self.assertThat(message.message_status_image.source, Eventually(Equals(message_status_read)))
0\ No newline at end of file206\ No newline at end of file
1207
=== added file 'telegram/autopilot/telegram/tests/test_Messaging.py'
--- telegram/autopilot/telegram/tests/test_Messaging.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/tests/test_Messaging.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,402 @@
1from telegram.tests import TelegramAppTestCase
2from telegram import emulators
3
4import os
5import dbus
6import time
7import datetime
8import threading
9# import subprocess
10import ubuntuuitoolkit
11
12from autopilot.matchers import Eventually
13from testtools.matchers import Equals, NotEquals
14from autopilot.display import Display
15from autopilot import platform
16from autopilot.utilities import sleep
17
18
19#from autopilot import logging as autopilot_logging
20#from telegram import displays_and_interactions as interactions
21
22message_sending_image = "qrc:/qml/files/msg_clock.png"
23message_received_image = "qrc:/qml/files/check_single_green.png"
24message_read_image = "qrc:/qml/files/check_double_green.png"
25media_received_image = "qrc:/qml/files/check_single_white.png"
26media_read_image = "qrc:/qml/files/check_double_white.png"
27
28
29class BaseTelegramTestCase(TelegramAppTestCase):
30
31 def setUp(self):
32 super(BaseTelegramTestCase, self).setUp()
33
34
35class SecretMessaging(BaseTelegramTestCase):
36
37 # Prerequisites:
38 # - User is already logged on
39 # - User has one contact which is online
40 # - Online contact is running on Telegram CLI
41
42 scenarios = [
43 ('textMessageSend', {'input': "textMessageSend"}),
44 ('textMessageSendReceive', {'input': "textMessageSendReceive"}),
45 ('photoMessageSend', {'input': "photoMessageSend"}),
46 # ('photoMessageReceive', {'input': "photoMessageReceive"}),
47 ]
48
49 def test_SecretMessage(self):
50
51 # Note the number of dialogs in the dialog list at the start of the test
52 account_page = self.main_view.account_page
53 dialog_list_page = account_page.get_dialog_list_page()
54 count = dialog_list_page.dialog_count
55
56 # Open the account panel by tapping the navigation menu icon
57 account_panel = account_page.open_account_panel()
58 self.assertThat(account_panel.opened, Eventually(Equals(True)))
59
60 # Select the secret chat option
61 account_panel.select_secret_chat()
62
63 # Select an online contact
64 apl = self.main_view.apl
65 contacts_page = apl.contacts_page
66 recipient = contacts_page.select_first_online_contact()
67 self.main_view.pointing_device.click_object(recipient)
68
69 # Create a new secret chat
70 self.assertThat(count, Eventually(Equals(count + 1)))
71 dialog_list_page.select_dialog_at_index(0)
72 dialog_page = apl.dialog_page
73
74 # Check that only system message is being displayed
75 message_list = dialog_page.account_message_list
76 initial_count = message_list.messages.count
77 self.assertThat(initial_count, Equals(1))
78
79 status_received = message_received_image
80 status_read = message_read_image
81
82 if "textMessage" in self.input or self.input == "photoMessageReceive":
83 # Send the first message
84
85 ts = time.time()
86 timestamp = datetime.datetime.fromtimestamp(ts).strftime('%y:%m:%d,%H:%M:%S')
87 message_to_send = "Autopilot:" + timestamp
88 if self.input == "textMessageSend":
89 message_to_send = message_to_send + " DO NOT REPLY"
90 elif self.input == "photoMessageReceive":
91 message_to_send = message_to_send + " SEND IMAGE"
92
93 dialog_page.enter_message(message_to_send)
94 dialog_page.message_area.select_attach_or_send()
95
96 elif self.input == "photoMessageSend":
97
98 if platform.model() == "Desktop":
99 return
100
101 dialog_page.message_area.select_attach_or_send()
102 dialog_page.message_area.select_attach_photo_option()
103 self.main_view.select_content_hub_app("Camera")
104
105 # Allow time to open the app
106 sleep(5)
107
108 display = Display.create()
109 screen_width = display.get_screen_width()
110 screen_height = display.get_screen_height()
111 button_x_pos = screen_width / 2.0
112 button_y_pos = screen_height - 100.0
113
114 # Click on the take photo button
115 self.main_view.pointing_device.move(button_x_pos, button_y_pos)
116 self.main_view.pointing_device.click()
117
118 # Allow time to take the photo
119 sleep(5)
120
121 # Tap the tick to return to Telegram
122 self.main_view.pointing_device.move(button_x_pos, button_y_pos)
123 self.main_view.pointing_device.click()
124
125 status_received = media_received_image
126 status_read = media_read_image
127
128 # Allow time for photo to be sent
129 sleep(5)
130
131 # Check that sent message appears in the dialog content
132 self.assertThat(message_list.messages.count, Eventually(Equals(initial_count + 1)))
133
134 # Check that the message received image is displayed for the sent message
135 index_of_sent_message = 0
136 message = message_list.get_message_at_index(index_of_sent_message)
137 status_image = message.message_status_image
138
139 if self.input == "photoMessageSend" and platform.model() != "Desktop":
140 status_image = message.account_message_media.media_message_status_image
141
142 self.assertThat(status_image.source, Eventually(Equals(status_received)))
143
144 if "Receive" in self.input:
145
146 index_of_sent_message = index_of_sent_message + 1
147
148 # Check for reply
149 self.assertThat(message_list.messages.count, Eventually(Equals(initial_count + 2)))
150
151 # Check that the message read image is displayed for the sent message
152 message = message_list.get_message_at_index(index_of_sent_message)
153 status_image = message.message_status_image
154
155 if self.input == "photoMessageSend" and platform.model() != "Desktop":
156 status_image = message.account_message_media.media_message_status_image
157
158 self.assertThat(status_image.source, Eventually(Equals(status_read)))
159
160
161
162class BasicMessaging(BaseTelegramTestCase):
163
164 scenarios = [
165 ('textMessageSend', {'input': "textMessageSend"}),
166 ('textMessageSendReceive', {'input': "textMessageSendReceive"}),
167 ('photoMessageSend', {'input': "photoMessageSend"}),
168 ('photoMessageReceive', {'input': "photoMessageReceive"}),
169 ]
170
171 def test_BasicMessage(self):
172
173 # Open the account panel by tapping the navigation menu icon
174 account_page = self.main_view.account_page
175 account_panel = account_page.open_account_panel()
176 self.assertThat(account_panel.opened, Eventually(Equals(True)))
177
178 # Select contacts
179 account_panel.select_contacts()
180
181 # Select an online contact
182 apl = self.main_view.apl
183 contacts_page = apl.contacts_page
184 recipient = contacts_page.select_first_online_contact()
185 self.main_view.pointing_device.click_object(recipient)
186
187 # Check that no messages are being displayed
188 dialog_page = apl.dialog_page
189 message_list = dialog_page.account_message_list
190 initial_count = message_list.messages.count
191
192 # Initialise status image values
193 status_received = message_received_image
194 status_read = message_read_image
195
196 if "textMessage" in self.input or self.input == "photoMessageReceive":
197
198 # Send the first message
199 ts = time.time()
200 timestamp = datetime.datetime.fromtimestamp(ts).strftime('%y:%m:%d,%H:%M:%S')
201 message_to_send = "Autopilot" + timestamp
202 if self.input == "textMessageSend":
203 message_to_send = message_to_send + " DO NOT REPLY"
204 elif self.input == "photoMessageReceive":
205 message_to_send = message_to_send + " SEND IMAGE"
206
207 dialog_page.enter_message(message_to_send)
208 dialog_page.message_area.select_attach_or_send()
209
210 elif self.input == "photoMessageSend":
211
212 if platform.model() == "Desktop":
213 return
214
215 dialog_page.message_area.select_attach_or_send()
216 dialog_page.message_area.select_attach_photo_option()
217 self.main_view.select_content_hub_app("Camera")
218
219 # Allow time to open the app
220 sleep(5)
221
222 display = Display.create()
223 screen_width = display.get_screen_width()
224 screen_height = display.get_screen_height()
225 button_x_pos = screen_width / 2.0
226 button_y_pos = screen_height - 100.0
227
228 # Click on the take photo button
229 self.main_view.pointing_device.move(button_x_pos, button_y_pos)
230 self.main_view.pointing_device.click()
231
232 # Allow time to take the photo
233 sleep(5)
234
235 # Tap the tick to return to Telegram
236 self.main_view.pointing_device.move(button_x_pos, button_y_pos)
237 self.main_view.pointing_device.click()
238
239 status_received = media_received_image
240 status_read = media_read_image
241
242 # Allow time for photo to be sent
243 sleep(5)
244
245 # Check that sent message appears in the dialog content
246 self.assertThat(message_list.messages.count, Eventually(Equals(initial_count + 1)))
247
248 # Check that the message received image is displayed for the sent message
249 index_of_sent_message = 0
250 message = message_list.get_message_at_index(index_of_sent_message)
251 status_image = message.message_status_image
252
253 if self.input == "photoMessageSend" and platform.model() != "Desktop":
254 status_image = message.account_message_media.media_message_status_image
255
256 self.assertThat(status_image.source, Eventually(Equals(status_received)))
257
258 if "Receive" in self.input:
259
260 index_of_sent_message = index_of_sent_message + 1
261
262 # Check for reply
263 self.assertThat(message_list.messages.count, Eventually(Equals(initial_count + 2)))
264
265 # Check that the message read image is displayed for the sent message
266 message = message_list.get_message_at_index(index_of_sent_message)
267 status_image = message.message_status_image
268
269 if self.input == "photoMessageSend" and platform.model() != "Desktop":
270 status_image = message.account_message_media.media_message_status_image
271
272 self.assertThat(status_image.source, Eventually(Equals(status_read)))
273
274
275class GroupMessaging(BaseTelegramTestCase):
276
277 scenarios = [
278 ('textMessageSend', {'input': "textMessageSend"}),
279 ('textMessageSendReceive', {'input': "textMessageSendReceive"}),
280 ('photoMessageSend', {'input': "photoMessageSend"}),
281 ('photoMessageReceive', {'input': "photoMessageReceive"}),
282 ]
283
284 def test_GroupMessage(self):
285
286 # Note the number of dialogs in the dialog list at the start of the test
287 account_page = self.main_view.account_page
288 dialog_list_page = account_page.get_dialog_list_page()
289 count = dialog_list_page.dialog_count
290
291 # Open the account panel by tapping the navigation menu icon
292 account_panel = account_page.open_account_panel()
293 self.assertThat(account_panel.opened, Eventually(Equals(True)))
294
295 # Select the group chat option
296 account_panel.select_group_chat()
297
298 # Select an online contact
299 apl = self.main_view.apl
300 contacts_page = apl.contacts_page
301 online_member_one = contacts_page.select_first_online_contact()
302 self.main_view.pointing_device.click_object(online_member_one)
303
304 # Select another contact
305 member_two = contacts_page.select_second_contact()
306 self.main_view.pointing_device.click_object(member_two)
307
308 # Add a group chat title
309 contacts_page.enter_group_chat_title('Autopilot Group Messaging')
310
311 # Select the group chat dialog just created
312 self.assertThat(count, Eventually(Equals(count + 1)))
313 dialog_list_page.select_dialog_at_index(0)
314 dialog_page = apl.dialog_page
315
316 # Check that only system message is being displayed
317 message_list = dialog_page.account_message_list
318 initial_count = message_list.messages.count
319 self.assertThat(initial_count, Equals(1))
320
321 # Initialise status image values
322 status_received = message_received_image
323 status_read = message_read_image
324
325 if "textMessage" in self.input or self.input == "photoMessageReceive":
326
327 # Generate and send the first message
328 ts = time.time()
329 timestamp = datetime.datetime.fromtimestamp(ts).strftime('%y:%m:%d,%H:%M:%S')
330 message_to_send = "Autopilot:" + timestamp
331 if self.input == "textMessageSend":
332 message_to_send = message_to_send + " DO NOT REPLY"
333 elif self.input == "photoMessageReceive":
334 message_to_send = message_to_send + " SEND IMAGE"
335
336 dialog_page.enter_message(message_to_send)
337 dialog_page.message_area.select_attach_or_send()
338
339 elif self.input == "photoMessageSend":
340
341 if platform.model() == "Desktop":
342 return
343
344 dialog_page.message_area.select_attach_or_send()
345 sleep(1)
346 dialog_page.message_area.select_attach_photo_option()
347 self.main_view.select_content_hub_app("Camera")
348
349 # Allow time to open the app
350 sleep(5)
351
352 display = Display.create()
353 screen_width = display.get_screen_width()
354 screen_height = display.get_screen_height()
355 button_x_pos = screen_width / 2.0
356 button_y_pos = screen_height - 100.0
357
358 # Click on the take photo button
359 self.main_view.pointing_device.move(button_x_pos, button_y_pos)
360 self.main_view.pointing_device.click()
361
362 # Allow time to take the photo
363 sleep(5)
364
365 # Tap the tick to return to Telegram
366 self.main_view.pointing_device.move(button_x_pos, button_y_pos)
367 self.main_view.pointing_device.click()
368
369 status_received = media_received_image
370 status_read = media_read_image
371
372 # Allow time for photo to be sent
373 sleep(5)
374
375 # Check that sent message appears in the dialog content
376 self.assertThat(message_list.messages.count, Eventually(Equals(initial_count + 1)))
377
378 # Check that the message received image is displayed for the sent message
379 index_of_sent_message = 0
380 message = message_list.get_message_at_index(index_of_sent_message)
381 status_image = message.message_status_image
382
383 if self.input == "photoMessageSend" and platform.model() != "Desktop":
384 status_image = message.account_message_media.media_message_status_image
385
386 self.assertThat(status_image.source, Eventually(Equals(status_received)))
387
388 if "Receive" in self.input:
389
390 index_of_sent_message = index_of_sent_message + 1
391
392 # Check for reply
393 self.assertThat(message_list.messages.count, Eventually(Equals(initial_count + 2)))
394
395 # Check that the double tick image is displayed for the read message
396 message = message_list.get_message_at_index(index_of_sent_message)
397 status_image = message.message_status_image
398
399 if self.input == "photoMessageSend" and platform.model() != "Desktop":
400 status_image = message.account_message_media.media_message_status_image
401
402 self.assertThat(status_image.source, Eventually(Equals(status_read)))
0403
=== added file 'telegram/autopilot/telegram/tests/test_Offline.py'
--- telegram/autopilot/telegram/tests/test_Offline.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/tests/test_Offline.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,54 @@
1from telegram.tests import TelegramAppTestCase
2from telegram import emulators
3
4# import subprocess
5import ubuntuuitoolkit
6
7from autopilot.matchers import Eventually
8from testtools.matchers import Equals
9from autopilot.display import Display
10from autopilot import platform
11from testtools import skipUnless
12
13class BaseTelegramTestCase(TelegramAppTestCase):
14
15 def setUp(self):
16 super(BaseTelegramTestCase, self).setUp()
17
18class OfflineTests(BaseTelegramTestCase):
19
20 @skipUnless(
21 platform.model() != "Desktop",
22 "Offline Test is only available on Device"
23 )
24
25 def test_check_for_offline_message(self):
26 display = Display.create()
27 screenWidth = display.get_screen_width()
28 screenHeight = display.get_screen_height()
29
30 #Pull menu from top
31 self.main_view.pointing_device.drag(screenWidth-202, 0, screenWidth-202, screenHeight)
32 #Tap Flight Mode switch
33 self.main_view.pointing_device.move(screenWidth-130,150)
34 self.main_view.pointing_device.click()
35 #Close menu
36 self.main_view.pointing_device.drag(0,screenHeight, 0,0)
37
38 account_page = self.main_view.account_page
39
40 # if account_page.get_default_header().title in ('Telegram', 'Connecting...'):
41 # print("WARNING - Please turn ON Airplane Mode")
42
43 self.assertThat(account_page.get_default_header().title, Eventually(Equals("Waiting for network...")))
44
45 #Pull menu from top
46 self.main_view.pointing_device.drag(screenWidth-180, 0, screenWidth-180, screenHeight)
47 #Tap Flight Mode switch
48 self.main_view.pointing_device.move(screenWidth-130,150)
49 self.main_view.pointing_device.click()
50 #Close menu
51 self.main_view.pointing_device.drag(0,screenHeight, 0,0)
52
53 # Check header no longer says offline message
54 self.assertThat(account_page.get_default_header().title, Eventually(Equals("Telegram")))
055
=== added file 'telegram/autopilot/telegram/tests/test_Profile.py'
--- telegram/autopilot/telegram/tests/test_Profile.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/tests/test_Profile.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,186 @@
1from telegram.tests import TelegramAppTestCase
2from telegram import emulators
3from telegram import utilities
4
5import os
6import dbus
7import time
8import datetime
9# import subprocess
10import ubuntuuitoolkit
11
12from autopilot.matchers import Eventually
13from testtools.matchers import Equals
14from autopilot.utilities import sleep
15
16messageTypeText = "Autopilot: Text INSTANT REPLY"
17
18class BaseTelegramTestCase(TelegramAppTestCase):
19
20 def setUp(self):
21 super(BaseTelegramTestCase, self).setUp()
22
23class ProfileTests(BaseTelegramTestCase):
24
25 def test_check_group_to_verify_members(self):
26 # Open the account panel by tapping the navigation menu icon
27 account_page = self.main_view.account_page
28 account_panel = account_page.open_account_panel()
29 self.assertThat(account_panel.opened, Eventually(Equals(True)))
30
31 # Select the secret chat option
32 account_panel.select_group_chat()
33
34 # Select first online contact
35 contacts_page = self.main_view.apl.contacts_page
36
37 # Select first contact
38 self.main_view.pointing_device.click_object(contacts_page.select_contact_at_index(0))
39 # Temporarily save fullname of contact
40 tempUser1Name = contacts_page.select_contact_at_index(0).fullName
41
42 # Select second contact
43 self.main_view.pointing_device.click_object(contacts_page.select_contact_at_index(1))
44 tempUser2Name = contacts_page.select_contact_at_index(1).fullName
45
46 #Enter group title and press Enter
47 contacts_page.enter_group_chat_title('ProfileTest-NewGroup')
48
49 #Assign dialog list
50 account_page = self.main_view.account_page
51 dialog_list_page = account_page.get_dialog_list_page()
52 count = dialog_list_page.dialog_count
53 self.assertThat(count, Eventually(Equals(count + 1)))
54 dialog_list_page.select_dialog_at_index(0)
55
56 #Press groupInfo button
57 self.main_view.apl.dialog_page.select_chat_info()
58
59 #Assign ProfilePage
60 profile_page = self.main_view.apl.profile_page
61
62 # Check user 1 is listed
63 self.assertThat(str(profile_page.profile_member_at_index(1).title), Equals(tempUser1Name))
64 # Check user 2 is listed
65 self.assertThat(str(profile_page.profile_member_at_index(0).title), Equals(tempUser2Name))
66
67
68 def test_check_blocked_user(self):
69 # Open the account panel by tapping the navigation menu icon
70 account_page = self.main_view.account_page
71 account_panel = account_page.open_account_panel()
72 self.assertThat(account_panel.opened, Eventually(Equals(True)))
73
74 # Select Contacts option
75 account_panel.select_contacts()
76
77 #Select first contact
78 contacts_page = self.main_view.apl.contacts_page
79 recipient = contacts_page.select_first_online_contact()
80 self.main_view.pointing_device.click_object(recipient)
81
82 dialog_page = self.main_view.apl.dialog_page
83 message_list = dialog_page.account_message_list
84 inital_count = message_list.messages.count
85
86 #Send message
87 dialog_page.enter_message(messageTypeText)
88 dialog_page.message_area.select_attach_or_send()
89
90 #Check received reply
91 self.assertThat(message_list.messages.count, Eventually(Equals(inital_count + 2)))
92
93 #Tap the groupInfo button
94 self.main_view.apl.dialog_page.select_chat_info()
95 #Assign ProfilePage
96 profile_page = self.main_view.apl.profile_page
97 #Turn on Block contact
98 switch = profile_page.switch_block
99 self.main_view.pointing_device.click_object(switch)
100 #Verify blocked user switch is turned ON
101 self.assertThat(switch.checked, Equals(True))
102 #Go back to dialog page
103 profile_page.select_back_button()
104 self.main_view.apl.clear_profile_page()
105
106 #Send message
107 dialog_page.enter_message(messageTypeText)
108 dialog_page.message_area.select_attach_or_send()
109
110 # Check that the sent message was read
111 message = None
112 for idx in range(0, message_list.messages.count):
113 message = message_list.get_message_at_index(idx)
114 if message.message_label.text == messageTypeText:
115 self.assertThat(message.message_status_image.source, Eventually(Equals("qrc:/qml/files/check_double_green.png")))
116 break
117 else:
118 message = None
119 self.assertThat(message is None, Equals(False))
120
121 # Check that no response was received (wait for 10 seconds)
122 sleep(10)
123 self.assertThat(message_list.messages.count, Equals(inital_count + 3))
124
125 #Tap the groupInfo button
126 self.main_view.apl.dialog_page.select_chat_info()
127 #Assign ProfilePage
128 profile_page = self.main_view.apl.profile_page
129 #Turn off Block contact.
130 switch = profile_page.switch_block
131 self.assertThat(switch.checked, Eventually(Equals(True)))
132 self.main_view.pointing_device.click_object(switch)
133 #Verify blocked user switch is turned OFF
134 self.assertThat(switch.checked, Eventually(Equals(False)))
135 #Go back to dialog page
136 profile_page.select_back_button()
137
138 #Check number of messages and send message
139 self.assertThat(message_list.messages.count, Equals(inital_count + 3))
140 #Send message
141 dialog_page.enter_message(messageTypeText)
142 dialog_page.message_area.select_attach_or_send()
143
144 #Check received reply
145 self.assertThat(message_list.messages.count, Eventually(Equals(inital_count + 5)))
146
147class ProfileDetails(BaseTelegramTestCase):
148
149 def test_verify_profile_details(self):
150 # Open the account panel by tapping the navigation menu icon
151 account_page = self.main_view.account_page
152 account_panel = account_page.open_account_panel()
153 self.assertThat(account_panel.opened, Eventually(Equals(True)))
154
155 # Select Contacts option
156 account_panel.select_contacts()
157
158 #Select first contact
159 contact_page = self.main_view.apl.contacts_page
160 contact = contact_page.select_contact_at_index(0)
161
162 self.main_view.pointing_device.click_object(contact)
163
164 self.main_view.apl.dialog_page.select_chat_info()
165
166 profile_page = self.main_view.apl.profile_page
167
168 # print(profile_page.profile_user_photo.get_properties())
169
170 # print("IMAGE SRC: " + profile_page.profile_user_photo.source)
171
172 sleep(3)
173
174 if profile_page.select_user_photo() is None:
175 #User does not have a profile image
176 print('WARNING - Profiles - Contact does not have Profile image')
177 else:
178 self.assertThat(profile_page.select_user_photo() is not None, Equals(True))
179
180 # Check the user has a name
181 if profile_page.profile_user_name.text is None:
182 raise RuntimeError("Profiles - Contact does not have Name")
183
184 # Check the user has a phone number
185 if profile_page.profile_user_phone_number.text is None:
186 raise RuntimeError("Profiles - Contact does not have valid Phone Number")
0\ No newline at end of file187\ No newline at end of file
1188
=== added file 'telegram/autopilot/telegram/utilities.py'
--- telegram/autopilot/telegram/utilities.py 1970-01-01 00:00:00 +0000
+++ telegram/autopilot/telegram/utilities.py 2016-11-14 11:39:33 +0000
@@ -0,0 +1,36 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2# Copyright 2016 Canonical
3#
4# This file is part of telegram-app.
5#
6# telegram-app is free software: you can redistribute it and/or modify it
7# under the terms of the GNU General Public License version 3, as published
8# by the Free Software Foundation.
9
10
11"""Telegram app helper functions"""
12
13from autopilot.input import Keyboard
14
15""" KEYBOARD UTILITIES """
16
17global mainKeyboard
18
19def enter_text_in_text_area(text_area, text):
20 #Assign keyboard type
21 mainKeyboard = Keyboard.create()
22
23 #Focus TextArea and begin typing
24 with mainKeyboard.focused_type(text_area) as kb:
25 kb.type(text)
26
27def enter_text_in_text_area_and_press_enter(text_area, text):
28 #Assign keyboard type
29 mainKeyboard = Keyboard.create()
30
31 #Focus TextArea and begin typing
32 with mainKeyboard.focused_type(text_area) as kb:
33 kb.type(text)
34
35 #Simulate 'Enter' key being pressed
36 mainKeyboard.press_and_release('Enter')
0\ No newline at end of file37\ No newline at end of file

Subscribers

People subscribed via source and target branches

to status/vote changes: