Merge lp:~heber013/ubuntu-system-tests/fix-gnome-software-tests into lp:ubuntu-system-tests

Proposed by Heber Parrucci
Status: Needs review
Proposed branch: lp:~heber013/ubuntu-system-tests/fix-gnome-software-tests
Merge into: lp:ubuntu-system-tests
Diff against target: 562 lines (+322/-67)
6 files modified
ubuntu_system_tests/helpers/application.py (+5/-0)
ubuntu_system_tests/helpers/gnome_sofware/cpo.py (+135/-7)
ubuntu_system_tests/helpers/krita/__init__.py (+19/-0)
ubuntu_system_tests/helpers/krita/app.py (+30/-0)
ubuntu_system_tests/host/target_setup.py (+1/-1)
ubuntu_system_tests/tests/test_gnome_software.py (+132/-59)
To merge this branch: bzr merge lp:~heber013/ubuntu-system-tests/fix-gnome-software-tests
Reviewer Review Type Date Requested Status
platform-qa-bot continuous-integration Approve
Canonical Platform QA Team Pending
Review via email: mp+336841@code.launchpad.net

Commit message

Fixing some gnome-software tests and adding new ones.

Description of the change

Fixing some gnome-software tests and adding new ones.

To post a comment you must log in.
Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)

Unmerged revisions

582. By Heber Parrucci

Fixing some gnome-software tests and adding new ones.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntu_system_tests/helpers/application.py'
2--- ubuntu_system_tests/helpers/application.py 2018-01-17 16:37:00 +0000
3+++ ubuntu_system_tests/helpers/application.py 2018-01-30 13:22:26 +0000
4@@ -220,3 +220,8 @@
5 def remove(self):
6 cmd = ['apt', 'remove', self.app_name, '-y']
7 run_command_with_sudo(cmd)
8+
9+ def ensure_uninstalled(self):
10+ if self._is_installed():
11+ cmd = ['apt', 'remove', self.app_name, '-y']
12+ run_command_with_sudo(cmd)
13
14=== modified file 'ubuntu_system_tests/helpers/gnome_sofware/cpo.py'
15--- ubuntu_system_tests/helpers/gnome_sofware/cpo.py 2018-01-18 20:52:36 +0000
16+++ ubuntu_system_tests/helpers/gnome_sofware/cpo.py 2018-01-30 13:22:26 +0000
17@@ -168,30 +168,45 @@
18 """Open the featured app's description
19 :return The page with the featured app's description
20 """
21+ time.sleep(10)
22 item = self.proxy.wait_select_single(BuilderName='GsFeatureTile', visible=True)
23- box = item.wait_select_single(BuilderName='box')
24- # This line throws an exception:
25+ box = item.wait_select_single(BuilderName='box',
26+ visible=True,
27+ sensitive=True,
28+ focus_on_click=True)
29 input_manager.pointer.click_object(box)
30 self.proxy.wait_select_single(
31 BuilderName='box_details',
32 visible=True)
33 return ItemDetailsPage(self.proxy.select_single(BuilderName='details_page'))
34
35+ @retry(stop_max_attempt_number=5,
36+ wait_fixed=3000,
37+ retry_on_exception=lambda exception: isinstance(
38+ exception, ValueError))
39+ def click_installed_tab(self):
40+ """Click on installed tab"""
41+ installed_button = self.proxy.select_single(BuilderName='button_installed_box',
42+ visible=True)
43+ input_manager.pointer.click_object(installed_button)
44+ return InstalledPage(self.proxy)
45+
46
47 class ResultsPage(GnomeSoftwareCPO):
48 def __init__(self, proxy):
49 super().__init__(proxy)
50+ self.results = []
51
52 def get_results(self, *args, **kwargs):
53 """Get the current results
54 :return the list with the current results or empty
55 """
56+ search = self.proxy.wait_select_single(BuilderName='list_box_search',
57+ *args,
58+ **kwargs)
59 attempts = 1
60 retries = kwargs.pop('retries', 10)
61 wait = kwargs.pop('wait', 5)
62- search = self.proxy.wait_select_single(BuilderName='list_box_search',
63- *args,
64- **kwargs)
65 # Wait until search finishes and return results
66 while attempts < retries:
67 try:
68@@ -201,10 +216,12 @@
69 except (DBusException, StateNotFoundError):
70 time.sleep(wait)
71 if search.get_children():
72- return search.get_children()
73+ self.results = search.get_children()
74+ return self.results
75 attempts += 1
76 continue
77- return []
78+ self.results = []
79+ return self.results
80
81 @staticmethod
82 def check_item(item, *args):
83@@ -252,9 +269,49 @@
84 visible=True)
85 return ItemDetailsPage(self.proxy.select_single(BuilderName='details_page'))
86
87+ def no_app_found(self):
88+ """Check if no apps were found in the search results
89+ :return True if no apps were found, False otherwise
90+ """
91+ try:
92+ self.proxy.select_single(BuilderName='noresults_grid_search',
93+ visible=True)
94+ return True
95+ except (DBusException, StateNotFoundError):
96+ return False
97+
98+ def get_item_details(self, app_name, **kwargs):
99+ """Get an item details from the results page
100+ :param app_name: the app name to look in the results
101+ :param kwargs: the filters to apply for the app details
102+ :return: the item details page if found or none
103+ """
104+ if not self.results:
105+ self.get_results()
106+ for item in self.results:
107+ if item.select_single(BuilderName='name_label').label == app_name:
108+ item_details = self.open_item(item)
109+ if item_details.check_details(**kwargs):
110+ return item_details
111+ super().click_back_button()
112+ return None
113+
114+ def get_item(self, app_name):
115+ """Get an item from the results page
116+ :param app_name: the app name to look in the results
117+ :return: the item object if found or none
118+ """
119+ for item in self.results:
120+ if item.select_single(BuilderName='name_label').label == app_name:
121+ return item
122+ return None
123+
124
125 class ItemDetailsPage(GnomeSoftwareCPO):
126 """Represent an item details"""
127+
128+ mapping = {'developer': 'label_details_developer_value'}
129+
130 def __init__(self, item_details_proxy):
131 super().__init__(item_details_proxy)
132
133@@ -268,3 +325,74 @@
134 return description_box.wait_select_many('GtkLabel')
135 except (DBusException, StateNotFoundError):
136 return []
137+
138+ def check_details(self, **kwargs):
139+ """
140+ Check if the item contains all attributes passed as parameter
141+ :param kwargs: the list of attributes to check
142+ :return: True if all attributes were found in the item, False otherwise
143+ """
144+ for _k, _v in kwargs.items():
145+ if not self.proxy.select_single(BuilderName=self.mapping.get(_k)).label == _v:
146+ return False
147+ return True
148+
149+ @retry(stop_max_attempt_number=10,
150+ wait_fixed=3000,
151+ retry_on_exception=lambda exception: isinstance(
152+ exception, ValueError))
153+ def click_install(self):
154+ """Click install button"""
155+ install_btn = self.proxy.wait_select_single(BuilderName='button_install',
156+ visible=True,
157+ can_focus=True)
158+ input_manager.pointer.click_object(install_btn)
159+ return self
160+
161+ @retry(stop_max_attempt_number=15,
162+ wait_fixed=3000,
163+ retry_on_exception=lambda exception: isinstance(
164+ exception, ValueError))
165+ def click_launch(self):
166+ """Click launch button"""
167+ launch_btn = self.proxy.wait_select_single(BuilderName='button_details_launch',
168+ visible=True,
169+ can_focus=True)
170+ input_manager.pointer.click_object(launch_btn)
171+
172+
173+class InstalledPage(GnomeSoftwareCPO):
174+ """Represent installed tab section"""
175+ def __init__(self, proxy):
176+ super().__init__(proxy)
177+
178+ def get_header(self):
179+ """Get the header object"""
180+ header = self.proxy.wait_select_single(BuilderName='header', visible=True)
181+ return header
182+
183+ @retry(stop_max_attempt_number=5,
184+ wait_fixed=3000,
185+ retry_on_exception=lambda exception: isinstance(
186+ exception, ValueError) or isinstance(exception, StateNotFoundError))
187+ def click_check_mark(self):
188+ """Click on check mark button"""
189+ check_mark = self.get_header().select_single(
190+ 'GtkButton',
191+ visible=True).select_single(
192+ 'GtkBox',
193+ visible=True)
194+ input_manager.pointer.click_object(check_mark)
195+ return self
196+
197+ def get_check_boxes(self):
198+ """Get installed apps checkboxes"""
199+ return self.proxy.wait_select_many(BuilderName='checkbox', visible=True)
200+
201+ def get_header_selection_menu(self):
202+ """Get the header selection menu object"""
203+ try:
204+ return self.proxy.wait_select_single(BuilderName='header_selection_menu_button',
205+ visible=True)
206+ except (DBusException, StateNotFoundError):
207+ return None
208
209=== added directory 'ubuntu_system_tests/helpers/krita'
210=== added file 'ubuntu_system_tests/helpers/krita/__init__.py'
211--- ubuntu_system_tests/helpers/krita/__init__.py 1970-01-01 00:00:00 +0000
212+++ ubuntu_system_tests/helpers/krita/__init__.py 2018-01-30 13:22:26 +0000
213@@ -0,0 +1,19 @@
214+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
215+
216+#
217+# Ubuntu System Tests
218+# Copyright (C) 2018 Canonical
219+#
220+# This program is free software: you can redistribute it and/or modify
221+# it under the terms of the GNU General Public License as published by
222+# the Free Software Foundation, either version 3 of the License, or
223+# (at your option) any later version.
224+#
225+# This program is distributed in the hope that it will be useful,
226+# but WITHOUT ANY WARRANTY; without even the implied warranty of
227+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
228+# GNU General Public License for more details.
229+#
230+# You should have received a copy of the GNU General Public License
231+# along with this program. If not, see <http://www.gnu.org/licenses/>.
232+#
233
234=== added file 'ubuntu_system_tests/helpers/krita/app.py'
235--- ubuntu_system_tests/helpers/krita/app.py 1970-01-01 00:00:00 +0000
236+++ ubuntu_system_tests/helpers/krita/app.py 2018-01-30 13:22:26 +0000
237@@ -0,0 +1,30 @@
238+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
239+
240+#
241+# Ubuntu System Tests
242+# Copyright (C) 2018 Canonical
243+#
244+# This program is free software: you can redistribute it and/or modify
245+# it under the terms of the GNU General Public License as published by
246+# the Free Software Foundation, either version 3 of the License, or
247+# (at your option) any later version.
248+#
249+# This program is distributed in the hope that it will be useful,
250+# but WITHOUT ANY WARRANTY; without even the implied warranty of
251+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
252+# GNU General Public License for more details.
253+#
254+# You should have received a copy of the GNU General Public License
255+# along with this program. If not, see <http://www.gnu.org/licenses/>.
256+#
257+
258+from ubuntu_system_tests.helpers.application import Deb
259+
260+APP_NAME = 'krita'
261+APP_ID = 'org.gnome.Krita'
262+
263+
264+class Krita(Deb):
265+
266+ def __init__(self):
267+ super().__init__(APP_NAME, APP_ID)
268
269=== modified file 'ubuntu_system_tests/host/target_setup.py'
270--- ubuntu_system_tests/host/target_setup.py 2018-01-16 17:19:00 +0000
271+++ ubuntu_system_tests/host/target_setup.py 2018-01-30 13:22:26 +0000
272@@ -605,7 +605,7 @@
273 ['systemctl', 'enable', service_name])
274
275
276-def main(config_path, snapd_https_proxy, snapd_http_proxy, username):
277+def main(config_path, snapd_https_proxy=None, snapd_http_proxy=None, username=None):
278 with open(config_path, 'r') as f:
279 config_json = json.loads(f.read())
280 runner = SetupRunner(config_json, snapd_https_proxy, snapd_http_proxy)
281
282=== modified file 'ubuntu_system_tests/tests/test_gnome_software.py'
283--- ubuntu_system_tests/tests/test_gnome_software.py 2018-01-18 21:17:21 +0000
284+++ ubuntu_system_tests/tests/test_gnome_software.py 2018-01-30 13:22:26 +0000
285@@ -15,18 +15,23 @@
286 #
287 # You should have received a copy of the GNU General Public License
288 # along with this program. If not, see <http://www.gnu.org/licenses/>.
289-
290+from autopilot.introspection import get_proxy_object_for_existing_process
291 from testtools import skipIf, skip
292
293+from ubuntu_system_tests.helpers.entangle.app import Entangle
294+from ubuntu_system_tests.helpers.gnome_core_apps.gnome_calculator.app import GnomeCalculator
295+from ubuntu_system_tests.helpers.gnome_sofware.app import GnomeSoftware
296+from ubuntu_system_tests.helpers.gnome_sofware.cpo import GnomeSoftwareCPO
297+from ubuntu_system_tests.helpers.krita.app import Krita
298+from ubuntu_system_tests.helpers.processes import (
299+ is_process_running,
300+ stop_process,
301+ get_process_id
302+)
303 from ubuntu_system_tests.helpers.session.release import get_release, XENIAL
304-
305-from ubuntu_system_tests.helpers.gnome_sofware.cpo import GnomeSoftwareCPO
306-from ubuntu_system_tests.helpers.testbed import run_command
307-from ubuntu_system_tests.helpers.gnome_sofware.app import GnomeSoftware
308+from ubuntu_system_tests.helpers.snapd.snapd import Snapd
309+from ubuntu_system_tests.helpers.testbed import run_command, run_command_with_sudo
310 from ubuntu_system_tests.tests.base import BaseUbuntuSystemTestCase
311-from ubuntu_system_tests.helpers.snapd.snapd import Snapd
312-from ubuntu_system_tests.helpers.chromium.app import Chromium
313-from ubuntu_system_tests.helpers.entangle.app import Entangle
314
315
316 class TestGnomeSoftware(BaseUbuntuSystemTestCase):
317@@ -169,13 +174,84 @@
318 for item in items:
319 self.assertTrue(self.app.check_item(item, 'image'))
320
321- @skip('This test never passes, open_featured_app function needs to be fixed')
322 def test_featured_application_description(self):
323 """Check there is a description after clicking the featured
324 application image"""
325 featured_details = self.app.open_featured_app()
326 self.assertTrue(featured_details.check_description())
327
328+ def test_check_installed_tab(self):
329+ """Check installed tab"""
330+ installed_page = self.app.click_installed_tab()
331+ installed_page.click_check_mark()
332+ self.assertIsNotNone(installed_page.get_header_selection_menu())
333+ self.assertGreater(installed_page.get_check_boxes(), 1)
334+
335+ def test_search_not_found(self):
336+ """Search for a non-existent app and verify no results are found"""
337+ self.app.click_search_button()
338+ results_page = self.app.write_search('nonexistent-app123')
339+ self.assertTrue(results_page.no_app_found())
340+
341+ def test_launch_app(self):
342+ # Perform the search
343+ self.app.click_search_button()
344+ results_page = self.app.write_search('cheese')
345+ results = results_page.get_results()
346+ item = results[0]
347+ # Open item and check details
348+ item_details = results_page.open_item(item)
349+ item_details.click_launch()
350+ self.assertTrue(is_process_running('cheese'))
351+
352+
353+class TestLaunchDebApp(BaseUbuntuSystemTestCase):
354+
355+ def setUp(self):
356+ super(BaseUbuntuSystemTestCase, self).setUp()
357+ run_command('killall gnome-software')
358+ self.root = GnomeSoftware().launch(app_type='gtk')
359+ self.app = GnomeSoftwareCPO(self.root)
360+
361+ def test_launch_app(self):
362+ # Perform the search
363+ self.app.click_search_button()
364+ results_page = self.app.write_search('cheese')
365+ # Open item and check details
366+ item_details = results_page.get_item_details('Cheese', developer='GNOME')
367+ item_details.click_launch()
368+ self.assertTrue(is_process_running('cheese'))
369+
370+ def tearDown(self):
371+ super(TestLaunchDebApp, self).tearDown()
372+ stop_process('cheese')
373+
374+
375+class TestLaunchSnapApp(BaseUbuntuSystemTestCase):
376+
377+ def setUp(self):
378+ super(TestLaunchSnapApp, self).setUp()
379+ self.snapd = Snapd()
380+ self.snap_app = 'gnome-sudoku'
381+ run_command('killall gnome-software')
382+ if not self.snapd.is_installed(self.snap_app):
383+ self.snapd.install(self.snap_app)
384+ self.addCleanup(self.snapd.remove, self.snap_app)
385+ self.root = GnomeSoftware().launch(app_type='gtk')
386+ self.cpo = GnomeSoftwareCPO(self.root)
387+
388+ def test_launch_app(self):
389+ # Perform the search
390+ self.cpo.click_search_button()
391+ results_page = self.cpo.write_search(self.snap_app)
392+ item_details = results_page.get_item_details(self.snap_app, developer='canonical')
393+ item_details.click_launch()
394+ self.assertTrue(is_process_running(self.snap_app))
395+
396+ def tearDown(self):
397+ super(TestLaunchSnapApp, self).tearDown()
398+ stop_process(self.snap_app)
399+
400
401 class TestGnomeSoftwareMixedResults(BaseUbuntuSystemTestCase):
402
403@@ -183,55 +259,40 @@
404 super(TestGnomeSoftwareMixedResults, self).setUp()
405 self.snapd = Snapd()
406 run_command('killall gnome-software')
407- self.is_snap_installed = self.snapd.is_installed('chromium')
408- if not self.is_snap_installed:
409- self.snapd.install('chromium')
410- self.chromium = Chromium()
411- self.is_deb_installed = self.chromium._is_installed()
412- if self.is_deb_installed:
413- self.chromium.remove()
414+ if self.snapd.is_installed('gnome-calculator'):
415+ self.snapd.remove('gnome-calculator')
416+ self.addCleanup(self.snapd.install, 'gnome-calculator')
417+ self.calculator_deb = GnomeCalculator()
418+ if not self.calculator_deb.is_installed():
419+ self.calculator_deb.install()
420+ self.addCleanup(self.calculator_deb.remove)
421 self.root = GnomeSoftware().launch(app_type='gtk')
422 self.app = GnomeSoftwareCPO(self.root)
423
424- @skip('This tests randomly fails, so it needs to be fixed')
425 def test_mixed_results(self):
426 """Check there are deb and snap versions"""
427 # Perform the search
428 self.app.click_search_button()
429- results_page = self.app.write_search('chromium')
430+ results_page = self.app.write_search('gnome calculator')
431 # Verify that there is more than one result
432 results = results_page.get_results()
433 self.assertTrue(len(results) > 1)
434- # Check item attributes in results
435- self.assertTrue(results_page.check_item(results[0],
436- 'image',
437- 'description_label'))
438- self.assertTrue(results_page.check_item(results[1],
439- 'image',
440- 'description_label'))
441- # Determine which result is a snap and which is a deb
442- if (results_page.get_app_name(results[0]) == 'Chromium'):
443- i = 0
444- j = 1
445- else:
446- i = 1
447- j = 0
448- # Check if the snap is visible as installed
449- self.assertTrue(results_page.check_item(results[i],
450+ # Check snap attributes in results
451+ snap_calculator = results_page.get_item('gnome-calculator')
452+ self.assertTrue(results_page.check_item(snap_calculator,
453+ 'image',
454+ 'description_label'))
455+ self.assertFalse(results_page.check_item(snap_calculator,
456+ 'label_installed'))
457+ # Check deb attributes in results
458+ self.assertTrue(results_page.check_item(results_page.get_item('GNOME Calculator'),
459+ 'image',
460+ 'description_label',
461+ 'star',
462 'label_installed'))
463- # Check if there is rating of the deb
464- self.assertTrue(results_page.check_item(results[j],
465- 'star'))
466- # Check if the deb is visible as not installed
467- self.assertFalse(results_page.check_item(results[j],
468- 'label_installed'))
469
470 def tearDown(self):
471 super(TestGnomeSoftwareMixedResults, self).tearDown()
472- if not self.is_snap_installed:
473- self.snapd.remove('chromium')
474- if self.is_deb_installed:
475- self.chromium.install()
476
477
478 class TestGnomeSoftwareInstalledSnap(BaseUbuntuSystemTestCase):
479@@ -243,10 +304,10 @@
480 self.is_installed = self.snapd.is_installed('hello-unity')
481 if not self.is_installed:
482 self.snapd.install('hello-unity')
483+ self.addCleanup(self.snapd.remove, 'hello-unity')
484 self.root = GnomeSoftware().launch(app_type='gtk')
485 self.app = GnomeSoftwareCPO(self.root)
486
487- @skip('In some cases this test freezes at setup, so it needs to be fixed')
488 def test_check_installed_snap(self):
489 """Check already installed snap"""
490 # Perform the search
491@@ -266,11 +327,6 @@
492 item_details = results_page.open_item(item)
493 self.assertTrue(item_details.check_description())
494
495- def tearDown(self):
496- super(TestGnomeSoftwareInstalledSnap, self).tearDown()
497- if not self.is_installed:
498- self.snapd.remove('hello-unity')
499-
500
501 class TestGnomeSoftwareNotInstalledSnap(BaseUbuntuSystemTestCase):
502
503@@ -281,6 +337,7 @@
504 self.is_installed = self.snapd.is_installed('hugo')
505 if self.is_installed:
506 self.snapd.remove('hugo')
507+ self.addCleanup(self.snapd.install, 'hugo')
508 self.root = GnomeSoftware().launch(app_type='gtk')
509 self.app = GnomeSoftwareCPO(self.root)
510
511@@ -306,11 +363,6 @@
512 item_details = results_page.open_item(item)
513 self.assertTrue(item_details.check_description())
514
515- def tearDown(self):
516- super(TestGnomeSoftwareNotInstalledSnap, self).tearDown()
517- if self.is_installed:
518- self.snapd.install('hugo')
519-
520
521 class TestGnomeSoftwareNotInstalledDeb(BaseUbuntuSystemTestCase):
522
523@@ -321,6 +373,7 @@
524 self.is_installed = self.entangle._is_installed()
525 if self.is_installed:
526 self.entangle.remove()
527+ self.addCleanup(self.entangle.install)
528 self.root = GnomeSoftware().launch(app_type='gtk')
529 self.app = GnomeSoftwareCPO(self.root)
530
531@@ -345,7 +398,27 @@
532 item_details = results_page.open_item(item)
533 self.assertTrue(item_details.check_description())
534
535- def tearDown(self):
536- super(TestGnomeSoftwareNotInstalledDeb, self).tearDown()
537- if self.is_installed:
538- self.entangle.install()
539+
540+class TestGnomeSoftwareInstallDeb(BaseUbuntuSystemTestCase):
541+
542+ def setUp(self):
543+ super(TestGnomeSoftwareInstallDeb, self).setUp()
544+ run_command('killall gnome-software')
545+ run_command_with_sudo('gnome-software')
546+ self.cpo = get_proxy_object_for_existing_process(pid=get_process_id('gnome-software'))
547+ self.app = Krita()
548+ self.app.ensure_uninstalled()
549+
550+ @skip('WIP')
551+ def test_install_deb_app(self):
552+ """Install a deb package"""
553+ # Perform the search
554+ self.cpo.click_search_button()
555+ results_page = self.cpo.write_search('krita')
556+ results_page.get_results()
557+ # Get the item we want to install
558+ item_details_page = results_page.get_item_details('Krita', developer='KDE')
559+ self.assertIsNotNone(item_details_page)
560+ item_details_page.click_install()
561+ self.addCleanup(self.app.ensure_uninstalled)
562+ self.assertTrue(self.app.is_installed())

Subscribers

People subscribed via source and target branches