Merge lp:~osomon/webbrowser-app/broken-lock into lp:webbrowser-app
- broken-lock
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Olivier Tilloy |
Approved revision: | 873 |
Merged at revision: | 868 |
Proposed branch: | lp:~osomon/webbrowser-app/broken-lock |
Merge into: | lp:webbrowser-app |
Diff against target: |
516 lines (+225/-169) 3 files modified
src/app/webbrowser/AddressBar.qml (+95/-93) src/app/webbrowser/Chrome.qml (+2/-2) src/app/webbrowser/SecurityCertificatePopover.qml (+128/-74) |
To merge this branch: | bzr merge lp:~osomon/webbrowser-app/broken-lock |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Michael Sheldon (community) | Approve | ||
Review via email: mp+247061@code.launchpad.net |
Commit message
Display a broken padlock icon when browsing a page loaded over an insecure connection.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:872
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:872
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Michael Sheldon (michael-sheldon) wrote : | # |
Looks good to me, the only possible addition that might be worth considering is adding a brief description to the certificate pop-up for the broken padlock like we currently have for the insecure content warning.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:873
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:873
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:873
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:873
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'src/app/webbrowser/AddressBar.qml' |
2 | --- src/app/webbrowser/AddressBar.qml 2014-12-12 23:51:36 +0000 |
3 | +++ src/app/webbrowser/AddressBar.qml 2015-01-21 15:39:32 +0000 |
4 | @@ -1,5 +1,5 @@ |
5 | /* |
6 | - * Copyright 2013-2014 Canonical Ltd. |
7 | + * Copyright 2013-2015 Canonical Ltd. |
8 | * |
9 | * This file is part of webbrowser-app. |
10 | * |
11 | @@ -41,7 +41,7 @@ |
12 | // XXX: for testing purposes only, do not use to modify the |
13 | // contents/behaviour of the internals of the component. |
14 | readonly property Item __textField: textField |
15 | - readonly property Item __actionButton: actionButton |
16 | + readonly property Item __actionButton: action |
17 | readonly property Item __bookmarkToggle: bookmarkToggle |
18 | |
19 | height: textField.height |
20 | @@ -64,117 +64,118 @@ |
21 | anchors.fill: parent |
22 | |
23 | primaryItem: Item { |
24 | - width: iconsRow.width |
25 | - height: iconsRow.height |
26 | + id: icons |
27 | + |
28 | + width: iconsRow.width + units.gu(1) |
29 | + height: units.gu(2) |
30 | + |
31 | Row { |
32 | id: iconsRow |
33 | - Item { |
34 | - height: textField.height |
35 | + |
36 | + spacing: units.gu(1) |
37 | + anchors { |
38 | + top: parent.top |
39 | + bottom: parent.bottom |
40 | + horizontalCenter: parent.horizontalCenter |
41 | + } |
42 | + |
43 | + Favicon { |
44 | + id: favicon |
45 | + anchors.verticalCenter: parent.verticalCenter |
46 | + visible: (addressbar.state == "") && addressbar.actualUrl.toString() && |
47 | + !internal.securityWarning && !internal.securityError |
48 | + } |
49 | + |
50 | + Icon { |
51 | + id: action |
52 | + |
53 | + height: parent.height |
54 | width: height |
55 | - visible: (addressbar.state != "") || !internal.secureConnection || !internal.securityWarning |
56 | - |
57 | - Favicon { |
58 | - id: favicon |
59 | - anchors.centerIn: parent |
60 | - visible: (addressbar.state == "") && addressbar.actualUrl.toString() && !internal.securityWarning |
61 | - } |
62 | - |
63 | - Item { |
64 | - id: certificatePopoverPositioner |
65 | - anchors.bottom: favicon.bottom |
66 | - anchors.horizontalCenter: favicon.horizontalCenter |
67 | - } |
68 | + |
69 | + visible: (addressbar.state == "editing") || |
70 | + (addressbar.state == "loading") || |
71 | + !addressbar.text |
72 | + |
73 | + enabled: addressbar.text |
74 | + opacity: enabled ? 1.0 : 0.3 |
75 | + |
76 | + readonly property bool loading: addressbar.state == "loading" |
77 | + readonly property bool editing: addressbar.state == "editing" |
78 | + readonly property bool reload: editing && addressbar.text && |
79 | + (addressbar.text == addressbar.actualUrl) |
80 | + readonly property bool looksLikeAUrl: internal.looksLikeAUrl(addressbar.text.trim()) |
81 | + |
82 | + name: loading ? "stop" : |
83 | + reload ? "reload" : |
84 | + looksLikeAUrl ? "stock_website" : "search" |
85 | |
86 | MouseArea { |
87 | - id: actionButton |
88 | objectName: "actionButton" |
89 | - anchors.fill: parent |
90 | - enabled: addressbar.text |
91 | - opacity: enabled ? 1.0 : 0.3 |
92 | |
93 | - Icon { |
94 | - id: actionIcon |
95 | - height: parent.height - units.gu(2) |
96 | - width: height |
97 | - anchors.centerIn: parent |
98 | - name: { |
99 | - switch (addressbar.state) { |
100 | - case "loading": |
101 | - return "stop" |
102 | - case "editing": |
103 | - if (addressbar.text && (addressbar.text == addressbar.actualUrl)) { |
104 | - return "reload" |
105 | - } else if (internal.looksLikeAUrl(addressbar.text.trim())) { |
106 | - return "stock_website" |
107 | - } else { |
108 | - return "search" |
109 | - } |
110 | - default: |
111 | - if (!favicon.visible) { |
112 | - if (internal.looksLikeAUrl(addressbar.text.trim())) { |
113 | - return "stock_website" |
114 | - } else { |
115 | - return "search" |
116 | - } |
117 | - } else { |
118 | - return "" |
119 | - } |
120 | - } |
121 | - } |
122 | + anchors { |
123 | + fill: parent |
124 | + margins: -units.gu(1) |
125 | } |
126 | |
127 | onClicked: { |
128 | - switch (actionIcon.name) { |
129 | - case "": |
130 | - break |
131 | - case "stop": |
132 | + if (action.loading) { |
133 | addressbar.requestStop() |
134 | - break |
135 | - case "reload": |
136 | + } else if (action.reload) { |
137 | addressbar.requestReload() |
138 | - break |
139 | - default: |
140 | + } else { |
141 | textField.accepted() |
142 | } |
143 | } |
144 | } |
145 | } |
146 | |
147 | - Item { |
148 | - id: securityDisplay |
149 | - height: textField.height |
150 | - width: securityIcon.width |
151 | - visible: internal.secureConnection && (addressbar.state == "") |
152 | - |
153 | - Icon { |
154 | - id: securityIcon |
155 | - anchors.centerIn: parent |
156 | - height: parent.height - units.gu(2) |
157 | - width: height |
158 | - name: "network-secure" |
159 | - } |
160 | - } |
161 | - |
162 | - Item { |
163 | - height: textField.height |
164 | - width: warningIcon.width |
165 | - visible: internal.securityWarning && (addressbar.state == "") |
166 | - |
167 | - Icon { |
168 | - id: warningIcon |
169 | - anchors.centerIn: parent |
170 | - height: parent.height - units.gu(2) |
171 | - width: height |
172 | - name: "security-alert" |
173 | - } |
174 | - } |
175 | + Icon { |
176 | + name: "network-secure" |
177 | + height: parent.height |
178 | + width: height |
179 | + visible: (addressbar.state == "") && internal.secureConnection |
180 | + } |
181 | + |
182 | + Image { |
183 | + source: "assets/broken_lock.png" |
184 | + height: parent.height |
185 | + fillMode: Image.PreserveAspectFit |
186 | + visible: (addressbar.state == "") && internal.securityError |
187 | + } |
188 | + |
189 | + Icon { |
190 | + name: "security-alert" |
191 | + height: parent.height |
192 | + width: height |
193 | + visible: (addressbar.state == "") && internal.securityWarning |
194 | + } |
195 | + } |
196 | + |
197 | + Item { |
198 | + id: certificatePopoverPositioner |
199 | + anchors { |
200 | + top: iconsRow.top |
201 | + bottom: iconsRow.bottom |
202 | + left: iconsRow.left |
203 | + } |
204 | + width: units.gu(2) |
205 | } |
206 | |
207 | MouseArea { |
208 | - enabled: securityDisplay.visible && addressbar.state != "editing" && addressbar.state != "loading" |
209 | - anchors.fill: parent |
210 | + enabled: addressbar.state == "" |
211 | + anchors { |
212 | + left: iconsRow.left |
213 | + leftMargin: -units.gu(1) |
214 | + right: iconsRow.right |
215 | + verticalCenter: parent.verticalCenter |
216 | + } |
217 | + height: textField.height |
218 | |
219 | - onClicked: addressbar.showSecurityCertificateDetails() |
220 | + onClicked: { |
221 | + if (internal.secureConnection || internal.securityError) { |
222 | + addressbar.showSecurityCertificateDetails() |
223 | + } |
224 | + } |
225 | } |
226 | } |
227 | |
228 | @@ -226,8 +227,8 @@ |
229 | MouseArea { |
230 | anchors { |
231 | fill: parent |
232 | - leftMargin: iconsRow.width |
233 | - rightMargin: bookmarkButton.width |
234 | + leftMargin: icons.width |
235 | + rightMargin: bookmarkToggle.width |
236 | } |
237 | visible: !textField.activeFocus |
238 | onClicked: { |
239 | @@ -243,6 +244,7 @@ |
240 | readonly property int securityLevel: addressbar.securityStatus ? addressbar.securityStatus.securityLevel : Oxide.SecurityStatus.SecurityLevelNone |
241 | readonly property bool secureConnection: addressbar.securityStatus ? (securityLevel == Oxide.SecurityStatus.SecurityLevelSecure || securityLevel == Oxide.SecurityStatus.SecurityLevelSecureEV || securityLevel == Oxide.SecurityStatus.SecurityLevelWarning) : false |
242 | readonly property bool securityWarning: addressbar.securityStatus ? (securityLevel == Oxide.SecurityStatus.SecurityLevelWarning) : false |
243 | + readonly property bool securityError: addressbar.securityStatus ? (securityLevel == Oxide.SecurityStatus.SecurityLevelError) : false |
244 | |
245 | property var securityCertificateDetails: null |
246 | |
247 | |
248 | === modified file 'src/app/webbrowser/Chrome.qml' |
249 | --- src/app/webbrowser/Chrome.qml 2014-12-12 09:48:34 +0000 |
250 | +++ src/app/webbrowser/Chrome.qml 2015-01-21 15:39:32 +0000 |
251 | @@ -1,5 +1,5 @@ |
252 | /* |
253 | - * Copyright 2013-2014 Canonical Ltd. |
254 | + * Copyright 2013-2015 Canonical Ltd. |
255 | * |
256 | * This file is part of webbrowser-app. |
257 | * |
258 | @@ -98,7 +98,7 @@ |
259 | verticalCenter: parent.verticalCenter |
260 | } |
261 | |
262 | - icon: chrome.webview ? chrome.webview.icon : "" |
263 | + icon: (chrome.webview && !chrome.webview.certificateError) ? chrome.webview.icon : "" |
264 | |
265 | loading: chrome.webview ? |
266 | chrome.webview.loading |
267 | |
268 | === modified file 'src/app/webbrowser/SecurityCertificatePopover.qml' |
269 | --- src/app/webbrowser/SecurityCertificatePopover.qml 2014-11-11 11:48:10 +0000 |
270 | +++ src/app/webbrowser/SecurityCertificatePopover.qml 2015-01-21 15:39:32 +0000 |
271 | @@ -1,5 +1,5 @@ |
272 | /* |
273 | - * Copyright 2014 Canonical Ltd. |
274 | + * Copyright 2014-2015 Canonical Ltd. |
275 | * |
276 | * This file is part of webbrowser-app. |
277 | * |
278 | @@ -27,6 +27,9 @@ |
279 | |
280 | property var securityStatus |
281 | |
282 | + readonly property bool isWarning: securityStatus.securityLevel == Oxide.SecurityStatus.SecurityLevelWarning |
283 | + readonly property bool isError: securityStatus.securityLevel == Oxide.SecurityStatus.SecurityLevelError |
284 | + |
285 | Column { |
286 | width: parent.width - units.gu(4) |
287 | anchors.horizontalCenter: parent.horizontalCenter |
288 | @@ -39,7 +42,7 @@ |
289 | |
290 | Column { |
291 | width: parent.width |
292 | - visible: securityStatus.securityLevel == Oxide.SecurityStatus.SecurityLevelWarning |
293 | + visible: certificatePopover.isWarning || certificatePopover.isError |
294 | spacing: units.gu(0.5) |
295 | |
296 | Row { |
297 | @@ -47,16 +50,60 @@ |
298 | spacing: units.gu(0.5) |
299 | |
300 | Icon { |
301 | + id: alertIcon |
302 | name: "security-alert" |
303 | height: units.gu(2) |
304 | width: height |
305 | } |
306 | |
307 | - Label { |
308 | - width: parent.width |
309 | - wrapMode: Text.WordWrap |
310 | - text: i18n.tr("This site has insecure content") |
311 | - fontSize: "x-small" |
312 | + Column { |
313 | + width: parent.width - alertIcon.width - parent.spacing |
314 | + height: childrenRect.height |
315 | + spacing: units.gu(0.5) |
316 | + |
317 | + Label { |
318 | + width: parent.width |
319 | + wrapMode: Text.WordWrap |
320 | + fontSize: "x-small" |
321 | + text: certificatePopover.isWarning ? |
322 | + i18n.tr("This site has insecure content") : |
323 | + i18n.tr("Identity Not Verified") |
324 | + } |
325 | + |
326 | + Label { |
327 | + width: parent.width |
328 | + wrapMode: Text.WordWrap |
329 | + visible: certificatePopover.isError |
330 | + fontSize: "x-small" |
331 | + text: i18n.tr("The identity of this website has not been verified.") |
332 | + } |
333 | + |
334 | + Label { |
335 | + width: parent.width |
336 | + wrapMode: Text.WordWrap |
337 | + visible: certificatePopover.isError |
338 | + fontSize: "x-small" |
339 | + text: { |
340 | + switch (securityStatus.certStatus) { |
341 | + case Oxide.SecurityStatus.CertStatusBadIdentity: |
342 | + return i18n.tr("Server certificate does not match the identity of the site.") |
343 | + case Oxide.SecurityStatus.CertStatusExpired: |
344 | + return i18n.tr("Server certificate has expired.") |
345 | + case Oxide.SecurityStatus.CertStatusDateInvalid: |
346 | + return i18n.tr("Server certificate contains invalid dates.") |
347 | + case Oxide.SecurityStatus.CertStatusAuthorityInvalid: |
348 | + return i18n.tr("Server certificate is issued by an entity that is not trusted.") |
349 | + case Oxide.SecurityStatus.CertStatusRevoked: |
350 | + return i18n.tr("Server certificate has been revoked.") |
351 | + case Oxide.SecurityStatus.CertStatusInvalid: |
352 | + return i18n.tr("Server certificate is invalid.") |
353 | + case Oxide.SecurityStatus.CertStatusInsecure: |
354 | + return i18n.tr("Server certificate is insecure.") |
355 | + default: |
356 | + return i18n.tr("Server certificate failed our security checks for an unknown reason.") |
357 | + } |
358 | + } |
359 | + } |
360 | } |
361 | } |
362 | |
363 | @@ -64,76 +111,83 @@ |
364 | width: parent.width |
365 | anchors.leftMargin: 0 |
366 | anchors.rightMargin: 0 |
367 | - } |
368 | - } |
369 | - |
370 | - Label { |
371 | - width: parent.width |
372 | - wrapMode: Text.WordWrap |
373 | - text: i18n.tr("You are connected to") |
374 | - fontSize: "x-small" |
375 | - } |
376 | - |
377 | - Label { |
378 | - width: parent.width |
379 | - wrapMode: Text.WordWrap |
380 | - text: securityStatus.certificate.subjectDisplayName |
381 | - fontSize: "x-small" |
382 | - } |
383 | - |
384 | - ThinDivider { |
385 | - width: parent.width |
386 | - anchors.leftMargin: 0 |
387 | - anchors.rightMargin: 0 |
388 | - visible: orgName.visible || localityName.visible || stateName.visible || countryName.visible |
389 | - } |
390 | - |
391 | - Label { |
392 | - width: parent.width |
393 | - wrapMode: Text.WordWrap |
394 | - visible: orgName.visible |
395 | - text: i18n.tr("Which is run by") |
396 | - fontSize: "x-small" |
397 | - } |
398 | - |
399 | - Label { |
400 | - id: orgName |
401 | - width: parent.width |
402 | - wrapMode: Text.WordWrap |
403 | - visible: text.length > 0 |
404 | - text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrOrganizationName).join(", ") |
405 | - fontSize: "x-small" |
406 | - } |
407 | - |
408 | - Label { |
409 | - id: localityName |
410 | - width: parent.width |
411 | - wrapMode: Text.WordWrap |
412 | - visible: text.length > 0 |
413 | - text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrLocalityName).join(", ") |
414 | - fontSize: "x-small" |
415 | - } |
416 | - |
417 | - Label { |
418 | - id: stateName |
419 | - width: parent.width |
420 | - wrapMode: Text.WordWrap |
421 | - visible: text.length > 0 |
422 | - text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrStateOrProvinceName).join(", ") |
423 | - fontSize: "x-small" |
424 | - } |
425 | - |
426 | - Label { |
427 | - id: countryName |
428 | - width: parent.width |
429 | - wrapMode: Text.WordWrap |
430 | - visible: text.length > 0 |
431 | - text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrCountryName).join(", ") |
432 | - fontSize: "x-small" |
433 | + visible: !certificatePopover.isError |
434 | + } |
435 | + } |
436 | + |
437 | + Column { |
438 | + width: parent.width |
439 | + spacing: units.gu(0.5) |
440 | + visible: !certificatePopover.isError |
441 | + |
442 | + Label { |
443 | + width: parent.width |
444 | + wrapMode: Text.WordWrap |
445 | + text: i18n.tr("You are connected to") |
446 | + fontSize: "x-small" |
447 | + } |
448 | + |
449 | + Label { |
450 | + width: parent.width |
451 | + wrapMode: Text.WordWrap |
452 | + text: securityStatus.certificate.subjectDisplayName |
453 | + fontSize: "x-small" |
454 | + } |
455 | + |
456 | + ThinDivider { |
457 | + width: parent.width |
458 | + anchors.leftMargin: 0 |
459 | + anchors.rightMargin: 0 |
460 | + visible: orgName.visible || localityName.visible || stateName.visible || countryName.visible |
461 | + } |
462 | + |
463 | + Label { |
464 | + width: parent.width |
465 | + wrapMode: Text.WordWrap |
466 | + visible: orgName.visible |
467 | + text: i18n.tr("Which is run by") |
468 | + fontSize: "x-small" |
469 | + } |
470 | + |
471 | + Label { |
472 | + id: orgName |
473 | + width: parent.width |
474 | + wrapMode: Text.WordWrap |
475 | + visible: text.length > 0 |
476 | + text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrOrganizationName).join(", ") |
477 | + fontSize: "x-small" |
478 | + } |
479 | + |
480 | + Label { |
481 | + id: localityName |
482 | + width: parent.width |
483 | + wrapMode: Text.WordWrap |
484 | + visible: text.length > 0 |
485 | + text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrLocalityName).join(", ") |
486 | + fontSize: "x-small" |
487 | + } |
488 | + |
489 | + Label { |
490 | + id: stateName |
491 | + width: parent.width |
492 | + wrapMode: Text.WordWrap |
493 | + visible: text.length > 0 |
494 | + text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrStateOrProvinceName).join(", ") |
495 | + fontSize: "x-small" |
496 | + } |
497 | + |
498 | + Label { |
499 | + id: countryName |
500 | + width: parent.width |
501 | + wrapMode: Text.WordWrap |
502 | + visible: text.length > 0 |
503 | + text: securityStatus.certificate.getSubjectInfo(Oxide.SslCertificate.PrincipalAttrCountryName).join(", ") |
504 | + fontSize: "x-small" |
505 | + } |
506 | } |
507 | |
508 | Item { |
509 | - height: units.gu(1.5) |
510 | + height: units.gu(1) |
511 | width: parent.width |
512 | } |
513 | } |
514 | |
515 | === added file 'src/app/webbrowser/assets/broken_lock@27.png' |
516 | Binary files src/app/webbrowser/assets/broken_lock@27.png 1970-01-01 00:00:00 +0000 and src/app/webbrowser/assets/broken_lock@27.png 2015-01-21 15:39:32 +0000 differ |
FAILED: Continuous integration, rev:871 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 1377/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 887 jenkins. qa.ubuntu. com/job/ generic- mediumtests- vivid/417 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- amd64-ci/ 135 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 135 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 135/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- i386-ci/ 135 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 779 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 885 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 885/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 17250 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-vivid/ 340 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-amd64/ 472 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-amd64/ 472/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 1377/rebuild
http://