Merge lp:~chocanto/ubuntu-docviewer-app/autopilot-tests into lp:ubuntu-docviewer-app/trunk
- autopilot-tests
- Merge into trunk
Proposed by
Anthony Granger
Status: | Merged |
---|---|
Approved by: | Anthony Granger |
Approved revision: | 14 |
Merged at revision: | 12 |
Proposed branch: | lp:~chocanto/ubuntu-docviewer-app/autopilot-tests |
Merge into: | lp:ubuntu-docviewer-app/trunk |
Diff against target: |
363 lines (+214/-33) 7 files modified
launcher/src/docviewer-launcher.pri (+1/-1) launcher/src/main.cpp (+20/-5) tests/autopilot/ubuntu_docviewer_app/emulators/main_window.py (+0/-4) tests/autopilot/ubuntu_docviewer_app/emulators/ubuntusdk.py (+165/-0) tests/autopilot/ubuntu_docviewer_app/files/plaintext.txt (+1/-0) tests/autopilot/ubuntu_docviewer_app/tests/__init__.py (+15/-10) tests/autopilot/ubuntu_docviewer_app/tests/test_docviewer.py (+12/-13) |
To merge this branch: | bzr merge lp:~chocanto/ubuntu-docviewer-app/autopilot-tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Anthony Granger | Approve | ||
Review via email:
|
Commit message
Base for all future autopilot testcases.
Description of the change
Base for all future autopilot testcases.
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anthony Granger (chocanto) : | # |
review:
Approve
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
review:
Needs Fixing
(continuous-integration)
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:14
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
review:
Approve
(continuous-integration)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'launcher/src/docviewer-launcher.pri' | |||
2 | --- launcher/src/docviewer-launcher.pri 2013-04-25 16:33:39 +0000 | |||
3 | +++ launcher/src/docviewer-launcher.pri 2013-06-28 21:59:24 +0000 | |||
4 | @@ -4,7 +4,7 @@ | |||
5 | 4 | # | 4 | # |
6 | 5 | #------------------------------------------------- | 5 | #------------------------------------------------- |
7 | 6 | 6 | ||
9 | 7 | QT += gui qml quick | 7 | QT += gui qml quick widgets |
10 | 8 | 8 | ||
11 | 9 | TARGET = ubuntu-docviewer-app | 9 | TARGET = ubuntu-docviewer-app |
12 | 10 | 10 | ||
13 | 11 | 11 | ||
14 | === modified file 'launcher/src/main.cpp' | |||
15 | --- launcher/src/main.cpp 2013-05-31 13:53:18 +0000 | |||
16 | +++ launcher/src/main.cpp 2013-06-28 21:59:24 +0000 | |||
17 | @@ -1,6 +1,7 @@ | |||
18 | 1 | #include <iostream> | 1 | #include <iostream> |
19 | 2 | 2 | ||
21 | 3 | #include <QGuiApplication> | 3 | #include <QApplication> |
22 | 4 | #include <QDir> | ||
23 | 4 | 5 | ||
24 | 5 | #include <QtQml/qqmlengine.h> | 6 | #include <QtQml/qqmlengine.h> |
25 | 6 | #include <QtQml/qqmlcomponent.h> | 7 | #include <QtQml/qqmlcomponent.h> |
26 | @@ -18,7 +19,7 @@ | |||
27 | 18 | 19 | ||
28 | 19 | int main(int argc, char *argv[]) | 20 | int main(int argc, char *argv[]) |
29 | 20 | { | 21 | { |
31 | 21 | QGuiApplication launcher(argc, argv); | 22 | QApplication launcher(argc, argv); //Testability work only with QApplication and not with QGuiApplication |
32 | 22 | 23 | ||
33 | 23 | QQmlEngine engine; | 24 | QQmlEngine engine; |
34 | 24 | QQmlComponent *component = new QQmlComponent(&engine); | 25 | QQmlComponent *component = new QQmlComponent(&engine); |
35 | @@ -35,7 +36,21 @@ | |||
36 | 35 | QString argument = ""; | 36 | QString argument = ""; |
37 | 36 | if (launcher.arguments().size() >= 2) | 37 | if (launcher.arguments().size() >= 2) |
38 | 37 | { | 38 | { |
40 | 38 | argument = launcher.arguments().at(1); | 39 | int i = 0; |
41 | 40 | for (i = 1; i < launcher.arguments().size(); i++) | ||
42 | 41 | { | ||
43 | 42 | if (launcher.arguments().at(i).at(0) != '-') | ||
44 | 43 | { | ||
45 | 44 | argument = launcher.arguments().at(i); | ||
46 | 45 | break; | ||
47 | 46 | } | ||
48 | 47 | } | ||
49 | 48 | |||
50 | 49 | if (i == launcher.arguments().size()) | ||
51 | 50 | { | ||
52 | 51 | displayUsage(); | ||
53 | 52 | return 0; | ||
54 | 53 | } | ||
55 | 39 | } | 54 | } |
56 | 40 | else | 55 | else |
57 | 41 | { | 56 | { |
58 | @@ -43,8 +58,8 @@ | |||
59 | 43 | return 0; | 58 | return 0; |
60 | 44 | } | 59 | } |
61 | 45 | 60 | ||
64 | 46 | 61 | QString absolutePath = QDir(argument).absolutePath(); | |
65 | 47 | File *file = new File(&argument); | 62 | File *file = new File(&absolutePath); |
66 | 48 | 63 | ||
67 | 49 | engine.rootContext()->setContextProperty("file", file); | 64 | engine.rootContext()->setContextProperty("file", file); |
68 | 50 | 65 | ||
69 | 51 | 66 | ||
70 | === modified file 'tests/autopilot/ubuntu_docviewer_app/emulators/main_window.py' | |||
71 | --- tests/autopilot/ubuntu_docviewer_app/emulators/main_window.py 2013-05-31 11:28:00 +0000 | |||
72 | +++ tests/autopilot/ubuntu_docviewer_app/emulators/main_window.py 2013-06-28 21:59:24 +0000 | |||
73 | @@ -16,9 +16,5 @@ | |||
74 | 16 | def __init__(self, app): | 16 | def __init__(self, app): |
75 | 17 | self.app = app | 17 | self.app = app |
76 | 18 | 18 | ||
77 | 19 | def get_qml_view(self): | ||
78 | 20 | """Get the main QML view""" | ||
79 | 21 | return self.app.select_single("QQuickView") | ||
80 | 22 | |||
81 | 23 | def get_toolbar(self): | 19 | def get_toolbar(self): |
82 | 24 | return self.app.select_single("Toolbar") | 20 | return self.app.select_single("Toolbar") |
83 | 25 | 21 | ||
84 | === added file 'tests/autopilot/ubuntu_docviewer_app/emulators/ubuntusdk.py' | |||
85 | --- tests/autopilot/ubuntu_docviewer_app/emulators/ubuntusdk.py 1970-01-01 00:00:00 +0000 | |||
86 | +++ tests/autopilot/ubuntu_docviewer_app/emulators/ubuntusdk.py 2013-06-28 21:59:24 +0000 | |||
87 | @@ -0,0 +1,165 @@ | |||
88 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
89 | 2 | # | ||
90 | 3 | # Copyright (C) 2013 Canonical Ltd | ||
91 | 4 | # | ||
92 | 5 | # This program is free software: you can redistribute it and/or modify | ||
93 | 6 | # it under the terms of the GNU General Public License version 3 as | ||
94 | 7 | # published by the Free Software Foundation. | ||
95 | 8 | # | ||
96 | 9 | # This program is distributed in the hope that it will be useful, | ||
97 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
98 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
99 | 12 | # GNU General Public License for more details. | ||
100 | 13 | # | ||
101 | 14 | # You should have received a copy of the GNU General Public License | ||
102 | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
103 | 16 | # | ||
104 | 17 | # Authored by: Nicholas Skaggs <nicholas.skaggs@canonical.com> | ||
105 | 18 | |||
106 | 19 | from testtools.matchers import Equals, NotEquals, Not, Is | ||
107 | 20 | from autopilot.matchers import Eventually | ||
108 | 21 | |||
109 | 22 | class ubuntusdk(object): | ||
110 | 23 | """An emulator class that makes it easy to interact with the ubuntu sdk applications.""" | ||
111 | 24 | |||
112 | 25 | def __init__(self, autopilot, app): | ||
113 | 26 | self.app = app | ||
114 | 27 | self.autopilot = autopilot | ||
115 | 28 | |||
116 | 29 | def get_qml_view(self): | ||
117 | 30 | """Get the main QML view""" | ||
118 | 31 | return self.app.select_single("QQuickView") | ||
119 | 32 | |||
120 | 33 | def get_object(self, typeName, name): | ||
121 | 34 | """Get a specific object""" | ||
122 | 35 | return self.app.select_single(typeName, objectName=name) | ||
123 | 36 | |||
124 | 37 | def get_objects(self, typeName, name): | ||
125 | 38 | """Get more than one object""" | ||
126 | 39 | return self.app.select_many(typeName, objectName=name) | ||
127 | 40 | |||
128 | 41 | def switch_to_tab(self, tab): | ||
129 | 42 | """Switch to the specified tab number""" | ||
130 | 43 | tabs = self.get_tabs() | ||
131 | 44 | currentTab = tabs.selectedTabIndex | ||
132 | 45 | |||
133 | 46 | #perform operations until tab == currentTab | ||
134 | 47 | while tab != currentTab: | ||
135 | 48 | if tab > currentTab: | ||
136 | 49 | self._previous_tab() | ||
137 | 50 | if tab < currentTab: | ||
138 | 51 | self._next_tab() | ||
139 | 52 | currentTab = tabs.selectedTabIndex | ||
140 | 53 | |||
141 | 54 | def toggle_toolbar(self): | ||
142 | 55 | """Toggle the toolbar between revealed and hidden""" | ||
143 | 56 | #check and see if the toolbar is open or not | ||
144 | 57 | if self.get_toolbar().opened: | ||
145 | 58 | self.hide_toolbar() | ||
146 | 59 | else: | ||
147 | 60 | self.open_toolbar() | ||
148 | 61 | |||
149 | 62 | def get_toolbar(self): | ||
150 | 63 | """Returns the toolbar in the main events view.""" | ||
151 | 64 | return self.app.select_single("Toolbar") | ||
152 | 65 | |||
153 | 66 | def get_toolbar_button(self, button): | ||
154 | 67 | """Returns the toolbar button at position index""" | ||
155 | 68 | toolbar = self.get_toolbar() | ||
156 | 69 | item = toolbar.get_children_by_type("QQuickItem")[0] | ||
157 | 70 | row = item.get_children_by_type("QQuickRow")[0] | ||
158 | 71 | buttonLoaders = row.get_children_by_type("QQuickLoader") | ||
159 | 72 | buttonLoader = buttonLoaders[button] | ||
160 | 73 | return buttonLoader | ||
161 | 74 | |||
162 | 75 | def click_toolbar_button(self, value): | ||
163 | 76 | """Clicks the toolbar button with value""" | ||
164 | 77 | #The toolbar button is assumed to be the following format | ||
165 | 78 | #ToolbarActions { | ||
166 | 79 | # Action { | ||
167 | 80 | # objectName: "name" | ||
168 | 81 | # text: value | ||
169 | 82 | toolbar = self.get_toolbar() | ||
170 | 83 | if not toolbar.opened: | ||
171 | 84 | self.open_toolbar() | ||
172 | 85 | item = toolbar.get_children_by_type("QQuickItem")[0] | ||
173 | 86 | row = item.get_children_by_type("QQuickRow")[0] | ||
174 | 87 | buttonList = row.get_children_by_type("QQuickLoader") | ||
175 | 88 | for button in buttonList: | ||
176 | 89 | itemList = lambda: self.get_objects("Action", button) | ||
177 | 90 | |||
178 | 91 | for item in itemList(): | ||
179 | 92 | if item.get_properties()['text'] == value: | ||
180 | 93 | self.autopilot.pointing_device.click_object(item) | ||
181 | 94 | |||
182 | 95 | def open_toolbar(self): | ||
183 | 96 | """Open the toolbar""" | ||
184 | 97 | qmlView = self.get_qml_view() | ||
185 | 98 | |||
186 | 99 | lineX = qmlView.x + qmlView.width * 0.50 | ||
187 | 100 | startY = qmlView.y + qmlView.height - 1 | ||
188 | 101 | stopY = qmlView.y + qmlView.height - 200 | ||
189 | 102 | |||
190 | 103 | self.autopilot.pointing_device.drag(lineX, startY, lineX, stopY) | ||
191 | 104 | self.autopilot.pointing_device.click() | ||
192 | 105 | self.autopilot.pointing_device.click() | ||
193 | 106 | |||
194 | 107 | def hide_toolbar(self): | ||
195 | 108 | """Hide the toolbar""" | ||
196 | 109 | qmlView = self.get_qml_view() | ||
197 | 110 | |||
198 | 111 | lineX = qmlView.x + qmlView.width * 0.50 | ||
199 | 112 | startY = qmlView.y + qmlView.height - 200 | ||
200 | 113 | stopY = qmlView.y + qmlView.height - 1 | ||
201 | 114 | |||
202 | 115 | self.autopilot.pointing_device.drag(lineX, startY, lineX, stopY) | ||
203 | 116 | self.autopilot.pointing_device.click() | ||
204 | 117 | self.autopilot.pointing_device.click() | ||
205 | 118 | |||
206 | 119 | def set_popup_value(self, popover, button, value): | ||
207 | 120 | """Changes the given popover selector to the request value | ||
208 | 121 | At the moment this only works for values that are currently visible. To | ||
209 | 122 | access the remaining items, a help method to drag and recheck is needed.""" | ||
210 | 123 | #The popover is assumed to be the following format | ||
211 | 124 | # Popover { | ||
212 | 125 | # Column { | ||
213 | 126 | # ListView { | ||
214 | 127 | # delegate: Standard { | ||
215 | 128 | # objectName: "name" | ||
216 | 129 | # text: value | ||
217 | 130 | |||
218 | 131 | self.autopilot.pointing_device.click_object(button) | ||
219 | 132 | #we'll get all matching objects, incase the popover is reused between buttons | ||
220 | 133 | itemList = lambda: self.get_objects("Standard", popover) | ||
221 | 134 | |||
222 | 135 | for item in itemList(): | ||
223 | 136 | if item.get_properties()['text'] == value: | ||
224 | 137 | self.autopilot.pointing_device.click_object(item) | ||
225 | 138 | |||
226 | 139 | def get_tabs(self): | ||
227 | 140 | """Return all tabs""" | ||
228 | 141 | return self.get_object("Tabs", "rootTabs") | ||
229 | 142 | |||
230 | 143 | def _previous_tab(self): | ||
231 | 144 | """Switch to the previous tab""" | ||
232 | 145 | qmlView = self.get_qml_view() | ||
233 | 146 | |||
234 | 147 | startX = qmlView.x + qmlView.width * 0.20 | ||
235 | 148 | stopX = qmlView.x + qmlView.width * 0.50 | ||
236 | 149 | lineY = qmlView.y + qmlView.height * 0.05 | ||
237 | 150 | |||
238 | 151 | self.autopilot.pointing_device.drag(startX, lineY, stopX, lineY) | ||
239 | 152 | self.autopilot.pointing_device.click() | ||
240 | 153 | self.autopilot.pointing_device.click() | ||
241 | 154 | |||
242 | 155 | def _next_tab(self): | ||
243 | 156 | """Switch to the next tab""" | ||
244 | 157 | qmlView = self.get_qml_view() | ||
245 | 158 | |||
246 | 159 | startX = qmlView.x + qmlView.width * 0.50 | ||
247 | 160 | stopX = qmlView.x + qmlView.width * 0.20 | ||
248 | 161 | lineY = qmlView.y + qmlView.height * 0.05 | ||
249 | 162 | |||
250 | 163 | self.autopilot.pointing_device.drag(startX, lineY, stopX, lineY) | ||
251 | 164 | self.autopilot.pointing_device.click() | ||
252 | 165 | self.autopilot.pointing_device.click() | ||
253 | 0 | 166 | ||
254 | === added directory 'tests/autopilot/ubuntu_docviewer_app/files' | |||
255 | === added file 'tests/autopilot/ubuntu_docviewer_app/files/plaintext.txt' | |||
256 | --- tests/autopilot/ubuntu_docviewer_app/files/plaintext.txt 1970-01-01 00:00:00 +0000 | |||
257 | +++ tests/autopilot/ubuntu_docviewer_app/files/plaintext.txt 2013-06-28 21:59:24 +0000 | |||
258 | @@ -0,0 +1,1 @@ | |||
259 | 1 | TEST | ||
260 | 0 | 2 | ||
261 | === modified file 'tests/autopilot/ubuntu_docviewer_app/tests/__init__.py' | |||
262 | --- tests/autopilot/ubuntu_docviewer_app/tests/__init__.py 2013-05-31 11:28:00 +0000 | |||
263 | +++ tests/autopilot/ubuntu_docviewer_app/tests/__init__.py 2013-06-28 21:59:24 +0000 | |||
264 | @@ -9,12 +9,14 @@ | |||
265 | 9 | 9 | ||
266 | 10 | import os.path | 10 | import os.path |
267 | 11 | 11 | ||
268 | 12 | from pprint import pprint | ||
269 | 13 | |||
270 | 12 | from autopilot.input import Mouse, Touch, Pointer | 14 | from autopilot.input import Mouse, Touch, Pointer |
271 | 13 | from autopilot.platform import model | 15 | from autopilot.platform import model |
272 | 14 | from autopilot.testcase import AutopilotTestCase | 16 | from autopilot.testcase import AutopilotTestCase |
273 | 15 | 17 | ||
274 | 16 | from ubuntu_docviewer_app.emulators.main_window import MainWindow | 18 | from ubuntu_docviewer_app.emulators.main_window import MainWindow |
276 | 17 | 19 | from ubuntu_docviewer_app.emulators.ubuntusdk import ubuntusdk | |
277 | 18 | 20 | ||
278 | 19 | class DocviewerTestCase(AutopilotTestCase): | 21 | class DocviewerTestCase(AutopilotTestCase): |
279 | 20 | 22 | ||
280 | @@ -22,34 +24,37 @@ | |||
281 | 22 | docviewer-app tests. | 24 | docviewer-app tests. |
282 | 23 | 25 | ||
283 | 24 | """ | 26 | """ |
284 | 27 | |||
285 | 25 | if model() == 'Desktop': | 28 | if model() == 'Desktop': |
286 | 26 | scenarios = [('with mouse', dict(input_device_class=Mouse))] | 29 | scenarios = [('with mouse', dict(input_device_class=Mouse))] |
287 | 27 | else: | 30 | else: |
288 | 28 | scenarios = [('with touch', dict(input_device_class=Touch))] | 31 | scenarios = [('with touch', dict(input_device_class=Touch))] |
289 | 29 | 32 | ||
291 | 30 | local_location = "../../ubuntu-docviewer-app.qml" | 33 | local_location = "../../ubuntu-docviewer-app" |
292 | 31 | 34 | ||
293 | 32 | def setUp(self): | 35 | def setUp(self): |
294 | 33 | self.pointing_device = Pointer(self.input_device_class.create()) | 36 | self.pointing_device = Pointer(self.input_device_class.create()) |
295 | 34 | super(DocviewerTestCase, self).setUp() | 37 | super(DocviewerTestCase, self).setUp() |
302 | 35 | if os.path.exists(self.local_location): | 38 | |
303 | 36 | self.launch_test_local() | 39 | def launch_test_local(self, arg): |
298 | 37 | else: | ||
299 | 38 | self.launch_test_installed() | ||
300 | 39 | |||
301 | 40 | def launch_test_local(self): | ||
304 | 41 | self.app = self.launch_test_application( | 40 | self.app = self.launch_test_application( |
305 | 42 | "qmlscene", | ||
306 | 43 | self.local_location, | 41 | self.local_location, |
307 | 42 | arg, | ||
308 | 44 | app_type='qt') | 43 | app_type='qt') |
309 | 45 | 44 | ||
311 | 46 | def launch_test_installed(self): | 45 | def launch_test_installed(self, arg): |
312 | 47 | self.app = self.launch_test_application( | 46 | self.app = self.launch_test_application( |
313 | 48 | "qmlscene", | 47 | "qmlscene", |
314 | 49 | "/usr/share/ubuntu-docviewer-app/ubuntu-docviewer-app.qml", | 48 | "/usr/share/ubuntu-docviewer-app/ubuntu-docviewer-app.qml", |
315 | 50 | "--desktop_file_hint=/usr/share/applications/ubuntu-docviewer-app.desktop", | 49 | "--desktop_file_hint=/usr/share/applications/ubuntu-docviewer-app.desktop", |
316 | 50 | arg, | ||
317 | 51 | app_type='qt') | 51 | app_type='qt') |
318 | 52 | 52 | ||
319 | 53 | @property | 53 | @property |
320 | 54 | def main_window(self): | 54 | def main_window(self): |
321 | 55 | return MainWindow(self.app) | 55 | return MainWindow(self.app) |
322 | 56 | |||
323 | 57 | @property | ||
324 | 58 | def ubuntusdk(self): | ||
325 | 59 | return ubuntusdk(self, self.app) | ||
326 | 60 | |||
327 | 56 | 61 | ||
328 | === modified file 'tests/autopilot/ubuntu_docviewer_app/tests/test_docviewer.py' | |||
329 | --- tests/autopilot/ubuntu_docviewer_app/tests/test_docviewer.py 2013-05-31 11:28:00 +0000 | |||
330 | +++ tests/autopilot/ubuntu_docviewer_app/tests/test_docviewer.py 2013-06-28 21:59:24 +0000 | |||
331 | @@ -19,20 +19,19 @@ | |||
332 | 19 | 19 | ||
333 | 20 | def setUp(self): | 20 | def setUp(self): |
334 | 21 | super(TestMainWindow, self).setUp() | 21 | super(TestMainWindow, self).setUp() |
335 | 22 | self.assertThat( | ||
336 | 23 | self.main_window.get_qml_view().visible, Eventually(Equals(True))) | ||
337 | 24 | 22 | ||
338 | 25 | def tearDown(self): | 23 | def tearDown(self): |
339 | 26 | super(TestMainWindow, self).tearDown() | 24 | super(TestMainWindow, self).tearDown() |
340 | 27 | 25 | ||
352 | 28 | def test_toolbar_shows(self): | 26 | def test_open_text_file(self): |
353 | 29 | """Make sure that dragging from the bottom reveals the hidden | 27 | |
354 | 30 | toolbar.""" | 28 | filePath = 'ubuntu_docviewer_app/files/plaintext.txt' |
355 | 31 | toolbar = self.main_window.get_toolbar() | 29 | |
356 | 32 | 30 | self.launch_test_local(filePath) | |
357 | 33 | x, y, w, h = toolbar.globalRect | 31 | |
358 | 34 | tx = x + (w / 2) | 32 | self.assertThat( |
359 | 35 | ty = y + (h - 2) | 33 | self.ubuntusdk.get_qml_view().visible, Eventually(Equals(True))) |
360 | 36 | 34 | ||
361 | 37 | self.pointing_device.drag(tx, ty, tx, ty - h) | 35 | #verify textbox is no longer empty |
362 | 38 | self.assertThat(toolbar.state, Eventually(Equals("spread"))) | 36 | # or |
363 | 37 | #verify the file size displayed is not 0 (maybe easier ?) |
FAILED: Continuous integration, rev:14 91.189. 93.70:8080/ job/ubuntu- docviewer- app-ci/ 36/ 91.189. 93.70:8080/ job/ubuntu- docviewer- app-quantal- amd64-ci/ 36/console 91.189. 93.70:8080/ job/ubuntu- docviewer- app-raring- amd64-ci/ 36/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- docviewer- app-ci/ 36/rebuild
http://