~ubuntu-branches/ubuntu/utopic/autopilot-legacy/utopic-proposed

« back to all changes in this revision

Viewing changes to autopilot/tests/functional/test_dbus_query.py

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2014-04-30 00:05:58 UTC
  • Revision ID: package-import@ubuntu.com-20140430000558-zmi37a3yf8podvwr
Tags: upstream-1.4.1+14.10.20140430
ImportĀ upstreamĀ versionĀ 1.4.1+14.10.20140430

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
 
2
#
 
3
# Autopilot Functional Test Tool
 
4
# Copyright (C) 2012-2013 Canonical
 
5
#
 
6
# This program is free software: you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation, either version 3 of the License, or
 
9
# (at your option) any later version.
 
10
#
 
11
# This program is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
#
 
19
 
 
20
 
 
21
import json
 
22
import os
 
23
import subprocess
 
24
import signal
 
25
from time import time
 
26
from tempfile import mktemp
 
27
from testtools import skipIf
 
28
from testtools.matchers import Equals, NotEquals, raises, LessThan, GreaterThan
 
29
 
 
30
from autopilot import platform
 
31
from autopilot.testcase import AutopilotTestCase
 
32
from autopilot.introspection.dbus import StateNotFoundError
 
33
 
 
34
 
 
35
@skipIf(platform.model() != "Desktop", "Only suitable on Desktop (WinMocker)")
 
36
class DbusQueryTests(AutopilotTestCase):
 
37
    """A collection of dbus query tests for autopilot."""
 
38
 
 
39
    def start_fully_featured_app(self):
 
40
        """Create an application that includes menus and other nested
 
41
        elements.
 
42
 
 
43
        """
 
44
        window_spec = {
 
45
            "Menu": [
 
46
                {
 
47
                    "Title": "File",
 
48
                    "Menu": [
 
49
                        "Open",
 
50
                        "Save",
 
51
                        "Save As",
 
52
                        "Quit"
 
53
                    ]
 
54
                },
 
55
                {
 
56
                    "Title": "Help",
 
57
                    "Menu": [
 
58
                        "Help 1",
 
59
                        "Help 2",
 
60
                        "Help 3",
 
61
                        "Help 4"
 
62
                    ]
 
63
                }
 
64
            ],
 
65
            "Contents": "TextEdit"
 
66
        }
 
67
 
 
68
        file_path = mktemp()
 
69
        json.dump(window_spec, open(file_path, 'w'))
 
70
        self.addCleanup(os.remove, file_path)
 
71
 
 
72
        return self.launch_test_application(
 
73
            'window-mocker', file_path, app_type="qt")
 
74
 
 
75
    def test_select_single_selects_only_available_object(self):
 
76
        """Must be able to select a single unique object."""
 
77
        app = self.start_fully_featured_app()
 
78
        main_window = app.select_single('QMainWindow')
 
79
        self.assertThat(main_window, NotEquals(None))
 
80
 
 
81
    def test_can_select_parent_of_root(self):
 
82
        """Must be able to select the parent of the root object."""
 
83
        root = self.start_fully_featured_app()
 
84
        root_parent = root.get_parent()
 
85
        self.assertThat(root.id, Equals(root_parent.id))
 
86
 
 
87
    def test_can_select_parent_of_normal_node(self):
 
88
        root = self.start_fully_featured_app()
 
89
        main_window = root.select_single('QMainWindow')
 
90
        window_parent = main_window.get_parent()
 
91
        self.assertThat(window_parent.id, Equals(root.id))
 
92
 
 
93
    def test_single_select_on_object(self):
 
94
        """Must be able to select a single unique child of an object."""
 
95
        app = self.start_fully_featured_app()
 
96
        main_win = app.select_single('QMainWindow')
 
97
        menu_bar = main_win.select_single('QMenuBar')
 
98
        self.assertThat(menu_bar, NotEquals(None))
 
99
 
 
100
    def test_select_multiple_on_object_returns_all(self):
 
101
        """Must be able to select all child objects."""
 
102
        app = self.start_fully_featured_app()
 
103
        main_win = app.select_single('QMainWindow')
 
104
        menu_bar = main_win.select_single('QMenuBar')
 
105
        menus = menu_bar.select_many('QMenu')
 
106
        self.assertThat(len(menus), Equals(2))
 
107
 
 
108
    def test_select_multiple_on_object_with_parameter(self):
 
109
        """Must be able to select a specific object determined by a
 
110
        parameter.
 
111
 
 
112
        """
 
113
        app = self.start_fully_featured_app()
 
114
        main_win = app.select_single('QMainWindow')
 
115
        menu_bar = main_win.select_single('QMenuBar')
 
116
        help_menu = menu_bar.select_many('QMenu', title='Help')
 
117
        self.assertThat(len(help_menu), Equals(1))
 
118
        self.assertThat(help_menu[0].title, Equals('Help'))
 
119
 
 
120
    def test_select_single_on_object_with_param(self):
 
121
        """Must only select a single unique object using a parameter."""
 
122
        app = self.start_fully_featured_app()
 
123
        main_win = app.select_single('QMainWindow')
 
124
        menu_bar = main_win.select_single('QMenuBar')
 
125
        help_menu = menu_bar.select_single('QMenu', title='Help')
 
126
        self.assertThat(help_menu, NotEquals(None))
 
127
        self.assertThat(help_menu.title, Equals('Help'))
 
128
 
 
129
    def test_select_many_uses_unique_object(self):
 
130
        """Given 2 objects of the same type with childen, selection on one will
 
131
        only get its children.
 
132
 
 
133
        """
 
134
        app = self.start_fully_featured_app()
 
135
        main_win = app.select_single('QMainWindow')
 
136
        menu_bar = main_win.select_single('QMenuBar')
 
137
        help_menu = menu_bar.select_single('QMenu', title='Help')
 
138
        actions = help_menu.select_many('QAction')
 
139
        self.assertThat(len(actions), Equals(5))
 
140
 
 
141
    def test_select_single_no_name_no_parameter_raises_exception(self):
 
142
        app = self.start_fully_featured_app()
 
143
        fn = lambda: app.select_single()
 
144
        self.assertThat(fn, raises(TypeError))
 
145
 
 
146
    def test_select_single_no_match_raises_exception(self):
 
147
        app = self.start_fully_featured_app()
 
148
        match_fn = lambda: app.select_single("QMadeupType")
 
149
        self.assertThat(match_fn, raises(StateNotFoundError('QMadeupType')))
 
150
 
 
151
    def test_select_single_parameters_only(self):
 
152
        app = self.start_fully_featured_app()
 
153
        main_win = app.select_single('QMainWindow')
 
154
        titled_help = main_win.select_single(title='Help')
 
155
        self.assertThat(titled_help, NotEquals(None))
 
156
        self.assertThat(titled_help.title, Equals('Help'))
 
157
 
 
158
    def test_select_single_parameters_no_match_raises_exception(self):
 
159
        app = self.start_fully_featured_app()
 
160
        match_fn = lambda: app.select_single(title="Non-existant object")
 
161
        self.assertThat(
 
162
            match_fn,
 
163
            raises(StateNotFoundError('*', title="Non-existant object"))
 
164
        )
 
165
 
 
166
    def test_select_single_returning_multiple_raises(self):
 
167
        app = self.start_fully_featured_app()
 
168
        fn = lambda: app.select_single('QMenu')
 
169
        self.assertThat(fn, raises(ValueError))
 
170
 
 
171
    def test_select_many_no_name_no_parameter_raises_exception(self):
 
172
        app = self.start_fully_featured_app()
 
173
        fn = lambda: app.select_single()
 
174
        self.assertThat(fn, raises(TypeError))
 
175
 
 
176
    def test_select_many_only_using_parameters(self):
 
177
        app = self.start_fully_featured_app()
 
178
        many_help_menus = app.select_many(title='Help')
 
179
        self.assertThat(len(many_help_menus), Equals(1))
 
180
 
 
181
    def test_select_many_with_no_parameter_matches_returns_empty_list(self):
 
182
        app = self.start_fully_featured_app()
 
183
        failed_match = app.select_many('QMenu', title='qwerty')
 
184
        self.assertThat(failed_match, Equals([]))
 
185
 
 
186
    def test_wait_select_single_succeeds_quickly(self):
 
187
        app = self.start_fully_featured_app()
 
188
        start_time = time()
 
189
        main_window = app.wait_select_single('QMainWindow')
 
190
        end_time = time()
 
191
        self.assertThat(main_window, NotEquals(None))
 
192
        self.assertThat(abs(end_time - start_time), LessThan(1))
 
193
 
 
194
    def test_wait_select_single_fails_slowly(self):
 
195
        app = self.start_fully_featured_app()
 
196
        start_time = time()
 
197
        fn = lambda: app.wait_select_single('QMadeupType')
 
198
        self.assertThat(fn, raises(StateNotFoundError('QMadeupType')))
 
199
        end_time = time()
 
200
        self.assertThat(abs(end_time - start_time), GreaterThan(9))
 
201
        self.assertThat(abs(end_time - start_time), LessThan(11))
 
202
 
 
203
 
 
204
@skipIf(platform.model() != "Desktop", "Only suitable on Desktop (WinMocker)")
 
205
class DbusCustomBusTests(AutopilotTestCase):
 
206
    """Test the ability to use custom dbus buses during a test."""
 
207
 
 
208
    def setUp(self):
 
209
        self.dbus_bus_addr = self._enable_custom_dbus_bus()
 
210
        super(DbusCustomBusTests, self).setUp()
 
211
 
 
212
    def _enable_custom_dbus_bus(self):
 
213
        p = subprocess.Popen(['dbus-launch'], stdout=subprocess.PIPE,
 
214
                             universal_newlines=True)
 
215
        output = p.communicate()
 
216
        results = output[0].split("\n")
 
217
        dbus_pid = int(results[1].split("=")[1])
 
218
        dbus_address = results[0].split("=", 1)[1]
 
219
 
 
220
        kill_dbus = lambda pid: os.killpg(pid, signal.SIGTERM)
 
221
        self.addCleanup(kill_dbus, dbus_pid)
 
222
 
 
223
        return dbus_address
 
224
 
 
225
    def _start_mock_app(self, dbus_bus):
 
226
        window_spec = {
 
227
            "Contents": "TextEdit"
 
228
        }
 
229
 
 
230
        file_path = mktemp()
 
231
        json.dump(window_spec, open(file_path, 'w'))
 
232
        self.addCleanup(os.remove, file_path)
 
233
 
 
234
        return self.launch_test_application(
 
235
            'window-mocker',
 
236
            file_path,
 
237
            app_type="qt",
 
238
            dbus_bus=dbus_bus,
 
239
        )
 
240
 
 
241
    def test_can_use_custom_dbus_bus(self):
 
242
        app = self._start_mock_app(self.dbus_bus_addr)
 
243
        self.assertThat(app, NotEquals(None))