Merge lp:~abreu-alexandre/webbrowser-app/webapp-homepage into lp:webbrowser-app
- webapp-homepage
- Merge into trunk
Status: | Superseded | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~abreu-alexandre/webbrowser-app/webapp-homepage | ||||||||||||
Merge into: | lp:webbrowser-app | ||||||||||||
Diff against target: |
872 lines (+288/-103) 16 files modified
po/webbrowser-app.pot (+14/-14) src/app/webcontainer/Chrome.qml (+1/-1) src/app/webcontainer/WebApp.qml (+4/-12) src/app/webcontainer/WebViewImplOxide.qml (+34/-20) src/app/webcontainer/WebViewImplWebkit.qml (+4/-1) src/app/webcontainer/WebappContainerWebview.qml (+5/-2) src/app/webcontainer/url-pattern-utils.cpp (+28/-7) src/app/webcontainer/url-pattern-utils.h (+2/-1) src/app/webcontainer/webapp-container.cpp (+24/-13) src/app/webcontainer/webapp-container.h (+1/-1) src/app/webcontainer/webapp-container.qml (+24/-9) tests/autopilot/webapp_container/tests/__init__.py (+43/-5) tests/autopilot/webapp_container/tests/fake_servers.py (+28/-8) tests/autopilot/webapp_container/tests/test_app_launch.py (+1/-1) tests/autopilot/webapp_container/tests/test_redirection_pattern.py (+59/-0) tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp (+16/-8) |
||||||||||||
To merge this branch: | bzr merge lp:~abreu-alexandre/webbrowser-app/webapp-homepage | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Olivier Tilloy | Approve | ||
David Barth (community) | Approve | ||
Review via email: mp+237456@code.launchpad.net |
Commit message
Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.
Description of the change
Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:751
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://
- 760. By Launchpad Translations on behalf of phablet-team
-
Launchpad automatic translations update.
David Barth (dbarth) : | # |
Olivier Tilloy (osomon) wrote : | # |
This changeset does much more than what it says on the tin. Please update the commit message to make it clear that this introduces StateSaver support for the webapp container. Also, wasn’t there a bug report to track the introduction of StateSaver? If so, please link it to the MR, and if not please file one and link it.
Olivier Tilloy (osomon) wrote : | # |
Given that updateBrowserUrl() is called only in one place, I don’t think factoring it out in its own function is useful. But it doesn’t harm either, I guess.
Code changes look good, not functionally tested.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:753
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:753
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:753
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:753
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 761. By Launchpad Translations on behalf of phablet-team
-
Launchpad automatic translations update.
- 762. By Launchpad Translations on behalf of phablet-team
-
Launchpad automatic translations update.
- 763. By Michael Sheldon
-
Detect 7 digital album downloads and request that they get unzipped by download manager. Fixes: 1365993
Approved by: PS Jenkins bot, Olivier Tilloy - 764. By PS Jenkins bot
-
Releasing 0.23+14.
10.20141015. 1-0ubuntu1 - 765. By PS Jenkins bot
-
Resync trunk
- 766. By Launchpad Translations on behalf of phablet-team
-
Launchpad automatic translations update.
- 767. By Launchpad Translations on behalf of phablet-team
-
Launchpad automatic translations update.
- 768. By Olivier Tilloy
-
Fix the override mechanism for navigator.
userAgent,
and add UA override rules for HSBC’s Brazilian mobile site and ESPN’s mobile site. Fixes: 1316259, 1380657
Approved by: Bill Filler, PS Jenkins bot - 769. By PS Jenkins bot
-
Releasing 0.23+14.
10.20141028~ rtm-0ubuntu1 - 770. By PS Jenkins bot
-
Resync trunk
- 771. By Riccardo Padovani
-
Fixed #1378975 - Fast double click on menu button opens menu twice Fixes: 1378975
Approved by: Olivier Tilloy - 772. By Riccardo Padovani
-
Updated the README
Approved by: Olivier Tilloy - 773. By Jean-Francois Moy
-
Twitter User Script - Hide the prompt to download the Android application. Fixes: 1352789, 1377268, 1378008
Approved by: Alexandre Abreu, Olivier Tilloy - 774. By PS Jenkins bot
-
Fix the override mechanism for navigator.
userAgent,
and add UA override rules for HSBC’s Brazilian mobile site and ESPN’s mobile site. Fixes: 1316259, 1380657
Approved by: Bill Filler, PS Jenkins bot - 775. By Olivier Tilloy
-
Prevent the browser from trying to download embedded flash applications. Fixes: 1379806
Approved by: Alexandre Abreu - 776. By Olivier Tilloy
-
Fix a harmless compilation warning found by clang (non-literal-
null-conversion ). - 777. By Olivier Tilloy
-
Update UITK autopilot test imports. Fixes: 1386276
Approved by: Zsombor Egri, PS Jenkins bot - 778. By PS Jenkins bot
-
Releasing 0.23+15.
04.20141029. 1-0ubuntu1 - 779. By Alexandre Abreu
-
Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.
Unmerged revisions
- 779. By Alexandre Abreu
-
Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.
Preview Diff
1 | === modified file 'po/webbrowser-app.pot' |
2 | --- po/webbrowser-app.pot 2014-10-03 14:41:14 +0000 |
3 | +++ po/webbrowser-app.pot 2014-10-20 22:12:22 +0000 |
4 | @@ -8,7 +8,7 @@ |
5 | msgstr "" |
6 | "Project-Id-Version: webbrowser-app\n" |
7 | "Report-Msgid-Bugs-To: \n" |
8 | -"POT-Creation-Date: 2014-09-22 14:59+0100\n" |
9 | +"POT-Creation-Date: 2014-10-20 17:24-0400\n" |
10 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
12 | "Language-Team: LANGUAGE <LL@li.org>\n" |
13 | @@ -117,7 +117,7 @@ |
14 | msgstr "" |
15 | |
16 | #: src/app/GeolocationPermissionRequest.qml:29 |
17 | -#: src/app/webcontainer/WebViewImplWebkit.qml:65 |
18 | +#: src/app/webcontainer/WebViewImplWebkit.qml:68 |
19 | msgid "This page wants to know your device’s location." |
20 | msgstr "" |
21 | |
22 | @@ -406,19 +406,19 @@ |
23 | msgid "search or enter an address" |
24 | msgstr "" |
25 | |
26 | -#: src/app/webbrowser/Browser.qml:179 |
27 | +#: src/app/webbrowser/Browser.qml:190 |
28 | msgid "Share" |
29 | msgstr "" |
30 | |
31 | -#: src/app/webbrowser/Browser.qml:193 |
32 | +#: src/app/webbrowser/Browser.qml:204 |
33 | msgid "History" |
34 | msgstr "" |
35 | |
36 | -#: src/app/webbrowser/Browser.qml:200 |
37 | +#: src/app/webbrowser/Browser.qml:211 |
38 | msgid "Open tabs" |
39 | msgstr "" |
40 | |
41 | -#: src/app/webbrowser/Browser.qml:206 src/app/webbrowser/TabsView.qml:57 |
42 | +#: src/app/webbrowser/Browser.qml:217 src/app/webbrowser/TabsView.qml:57 |
43 | msgid "New tab" |
44 | msgstr "" |
45 | |
46 | @@ -445,19 +445,19 @@ |
47 | msgid "Done" |
48 | msgstr "" |
49 | |
50 | -#: src/app/webbrowser/HistoryView.qml:113 |
51 | +#: src/app/webbrowser/HistoryView.qml:112 |
52 | msgid "Clear" |
53 | msgstr "" |
54 | |
55 | -#: src/app/webbrowser/HistoryView.qml:127 |
56 | +#: src/app/webbrowser/HistoryView.qml:126 |
57 | msgid "Delete all history?" |
58 | msgstr "" |
59 | |
60 | -#: src/app/webbrowser/HistoryView.qml:130 |
61 | +#: src/app/webbrowser/HistoryView.qml:129 |
62 | msgid "Yes" |
63 | msgstr "" |
64 | |
65 | -#: src/app/webbrowser/HistoryView.qml:139 |
66 | +#: src/app/webbrowser/HistoryView.qml:138 |
67 | msgid "No" |
68 | msgstr "" |
69 | |
70 | @@ -481,7 +481,7 @@ |
71 | msgid "Tap to view" |
72 | msgstr "" |
73 | |
74 | -#: src/app/webbrowser/TabsView.qml:115 |
75 | +#: src/app/webbrowser/TabsView.qml:114 |
76 | msgid "Add" |
77 | msgstr "" |
78 | |
79 | @@ -497,15 +497,15 @@ |
80 | msgid "Ubuntu Web Browser" |
81 | msgstr "" |
82 | |
83 | -#: src/app/webcontainer/AccountsLoginPage.qml:87 |
84 | +#: src/app/webcontainer/AccountsLoginPage.qml:91 |
85 | msgid "No local account found for " |
86 | msgstr "" |
87 | |
88 | -#: src/app/webcontainer/AccountsLoginPage.qml:92 |
89 | +#: src/app/webcontainer/AccountsLoginPage.qml:96 |
90 | msgid "Skip account creation step" |
91 | msgstr "" |
92 | |
93 | -#: src/app/webcontainer/AccountsLoginPage.qml:141 |
94 | +#: src/app/webcontainer/AccountsLoginPage.qml:145 |
95 | msgid "Add account" |
96 | msgstr "" |
97 | |
98 | |
99 | === modified file 'src/app/webcontainer/Chrome.qml' |
100 | --- src/app/webcontainer/Chrome.qml 2014-07-29 21:51:07 +0000 |
101 | +++ src/app/webcontainer/Chrome.qml 2014-10-20 22:12:22 +0000 |
102 | @@ -82,7 +82,7 @@ |
103 | |
104 | Favicon { |
105 | anchors.centerIn: parent |
106 | - source: chrome.webview.icon |
107 | + source: chrome.webview ? chrome.webview.icon : null |
108 | } |
109 | } |
110 | |
111 | |
112 | === modified file 'src/app/webcontainer/WebApp.qml' |
113 | --- src/app/webcontainer/WebApp.qml 2014-10-03 14:41:14 +0000 |
114 | +++ src/app/webcontainer/WebApp.qml 2014-10-20 22:12:22 +0000 |
115 | @@ -36,9 +36,10 @@ |
116 | property alias oxide: webview.withOxide |
117 | property alias webappName: webview.webappName |
118 | property alias webappUrlPatterns: webview.webappUrlPatterns |
119 | - property alias popupRedirectionUrlPrefix: webview.popupRedirectionUrlPrefix |
120 | + property alias popupRedirectionUrlPrefixPattern: webview.popupRedirectionUrlPrefixPattern |
121 | property alias webviewOverrideFile: webview.webviewOverrideFile |
122 | property string localUserAgentOverride: "" |
123 | + property alias blockOpenExternalUrls: webview.blockOpenExternalUrls |
124 | |
125 | property bool backForwardButtonsVisible: false |
126 | property bool chromeVisible: false |
127 | @@ -69,10 +70,12 @@ |
128 | } |
129 | |
130 | Item { |
131 | + id: webviewContainer |
132 | anchors.fill: parent |
133 | |
134 | WebappContainerWebview { |
135 | id: webview |
136 | + objectName: "webview" |
137 | |
138 | anchors { |
139 | left: parent.left |
140 | @@ -179,15 +182,4 @@ |
141 | actionsContext: actionManager.globalContext |
142 | model: UnityWebApps.UnityWebappsAppModel { searchPath: webappModelSearchPath } |
143 | } |
144 | - |
145 | - function isValidContainedUrl(url) { |
146 | - if (!url || url.length === 0 || url === 'about:blank') { |
147 | - return false |
148 | - } |
149 | - if (popupRedirectionUrlPrefix.length !== 0 |
150 | - && url.indexOf(popupRedirectionUrlPrefix) === 0) { |
151 | - return false |
152 | - } |
153 | - return true |
154 | - } |
155 | } |
156 | |
157 | === modified file 'src/app/webcontainer/WebViewImplOxide.qml' |
158 | --- src/app/webcontainer/WebViewImplOxide.qml 2014-08-19 08:42:30 +0000 |
159 | +++ src/app/webcontainer/WebViewImplOxide.qml 2014-10-20 22:12:22 +0000 |
160 | @@ -33,7 +33,16 @@ |
161 | property string webappName: "" |
162 | property string localUserAgentOverride: "" |
163 | property var webappUrlPatterns: null |
164 | - property string popupRedirectionUrlPrefix: "" |
165 | + property string popupRedirectionUrlPrefixPattern: "" |
166 | + |
167 | + // Mostly used for testing & avoid external urls to |
168 | + // "leak" in the default browser |
169 | + property bool blockOpenExternalUrls: false |
170 | + |
171 | + // Those signals are used for testing purposes to externally |
172 | + // track down the various internal logic & steps of a popup lifecycle. |
173 | + signal openExternalUrlTriggered(string url) |
174 | + signal gotRedirectionUrl(string url) |
175 | |
176 | currentWebview: webview |
177 | |
178 | @@ -48,6 +57,9 @@ |
179 | } |
180 | } |
181 | |
182 | + StateSaver.properties: "url" |
183 | + StateSaver.enabled: true |
184 | + |
185 | function shouldOpenPopupsInDefaultBrowser() { |
186 | return formFactor !== "desktop"; |
187 | } |
188 | @@ -70,6 +82,13 @@ |
189 | disposition === Oxide.NavigationRequest.DispositionNewForegroundTab; |
190 | } |
191 | |
192 | + function openUrlExternally(url) { |
193 | + webview.openExternalUrlTriggered(url) |
194 | + if (! webview.blockOpenExternalUrls) { |
195 | + Qt.openUrlExternally(url) |
196 | + } |
197 | + } |
198 | + |
199 | function shouldAllowNavigationTo(url) { |
200 | // The list of url patterns defined by the webapp takes precedence over command line |
201 | if (isRunningAsANamedWebapp()) { |
202 | @@ -113,36 +132,31 @@ |
203 | return |
204 | } |
205 | |
206 | + var redirectionPatternMatch = url.match(popupRedirectionUrlPrefixPattern); |
207 | var isRedirectionUrl = |
208 | - popupRedirectionUrlPrefix.length !== 0 |
209 | - && url.indexOf(popupRedirectionUrlPrefix) === 0; |
210 | - |
211 | + popupRedirectionUrlPrefixPattern |
212 | + && redirectionPatternMatch |
213 | + && redirectionPatternMatch.length >= 2; |
214 | var targetUrl = url; |
215 | if (isRedirectionUrl) { |
216 | - // Extract the target URL. |
217 | - targetUrl = url.slice(popupRedirectionUrlPrefix.length); |
218 | - // Quick fix for http://pad.lv/1358622 (trim trailing parameters). |
219 | - // A proper solution would probably involve regexps instead of a |
220 | - // simple redirection prefix. |
221 | - var extraParams = targetUrl.indexOf("&"); |
222 | - if (extraParams !== -1) { |
223 | - targetUrl = targetUrl.slice(0, extraParams); |
224 | - } |
225 | - // Decode it. |
226 | - targetUrl = decodeURIComponent(targetUrl); |
227 | + // Assume that the first group is the matching one |
228 | + targetUrl = redirectionPatternMatch[1]; |
229 | + console.debug("Got a redirection URL with target URL: " + targetUrl) |
230 | + targetUrl = decodeURIComponent(targetUrl) |
231 | + gotRedirectionUrl(targetUrl) |
232 | } |
233 | |
234 | if (webview.shouldAllowNavigationTo(targetUrl)) { |
235 | console.debug('Redirecting popup browsing ' + targetUrl + ' in the current container window.') |
236 | request.action = Oxide.NavigationRequest.ActionReject |
237 | - webappContainerHelper.browseToUrlRequested(webview, url.slice(url.indexOf(popupRedirectionUrlPrefix))) |
238 | + webappContainerHelper.browseToUrlRequested(webview, targetUrl) |
239 | return |
240 | } |
241 | |
242 | if (shouldOpenPopupsInDefaultBrowser()) { |
243 | console.debug('Opening popup window ' + targetUrl + ' in the browser window.') |
244 | request.action = Oxide.NavigationRequest.ActionReject |
245 | - Qt.openUrlExternally(targetUrl) |
246 | + openUrlExternally(targetUrl) |
247 | return; |
248 | } |
249 | return |
250 | @@ -179,7 +193,7 @@ |
251 | |
252 | if (request.action === Oxide.NavigationRequest.ActionReject) { |
253 | console.debug('Opening: ' + url + ' in the browser window.') |
254 | - Qt.openUrlExternally(url) |
255 | + openUrlExternally(url) |
256 | } |
257 | } |
258 | |
259 | @@ -203,7 +217,7 @@ |
260 | if ( ! isNewForegroundWebViewDisposition(request.disposition) && |
261 | ! webview.shouldAllowNavigationTo(url)) { |
262 | request.action = Oxide.NavigationRequest.ActionReject |
263 | - Qt.openUrlExternally(url); |
264 | + openUrlExternally(url); |
265 | popup.close() |
266 | return; |
267 | } |
268 | @@ -233,7 +247,7 @@ |
269 | return; |
270 | |
271 | if (_url != 'about:blank' && ! webview.shouldAllowNavigationTo(_url)) { |
272 | - Qt.openUrlExternally(_url); |
273 | + openUrlExternally(_url); |
274 | popup.close() |
275 | } |
276 | } |
277 | |
278 | === modified file 'src/app/webcontainer/WebViewImplWebkit.qml' |
279 | --- src/app/webcontainer/WebViewImplWebkit.qml 2014-07-29 21:51:07 +0000 |
280 | +++ src/app/webcontainer/WebViewImplWebkit.qml 2014-10-20 22:12:22 +0000 |
281 | @@ -34,7 +34,7 @@ |
282 | property string webappName: "" |
283 | property var webappUrlPatterns: null |
284 | property string localUserAgentOverride: "" |
285 | - property string popupRedirectionUrlPrefix: "" |
286 | + property string popupRedirectionUrlPrefixPattern: "" |
287 | |
288 | function getUAString() { |
289 | return webview.localUserAgentOverride.length === 0 ? undefined : webview.localUserAgentOverride |
290 | @@ -53,6 +53,9 @@ |
291 | } |
292 | } |
293 | |
294 | + StateSaver.properties: "url" |
295 | + StateSaver.enabled: true |
296 | + |
297 | property bool lastLoadFailed: false |
298 | onLoadingChanged: { |
299 | lastLoadFailed = (loadRequest.status === WebView.LoadFailedStatus) |
300 | |
301 | === modified file 'src/app/webcontainer/WebappContainerWebview.qml' |
302 | --- src/app/webcontainer/WebappContainerWebview.qml 2014-09-02 06:29:12 +0000 |
303 | +++ src/app/webcontainer/WebappContainerWebview.qml 2014-10-20 22:12:22 +0000 |
304 | @@ -33,11 +33,13 @@ |
305 | property var currentWebview: webappContainerWebViewLoader.item |
306 | property var webappUrlPatterns |
307 | property string localUserAgentOverride: "" |
308 | - property string popupRedirectionUrlPrefix: "" |
309 | + property string popupRedirectionUrlPrefixPattern: "" |
310 | property url webviewOverrideFile: "" |
311 | + property bool blockOpenExternalUrls: false |
312 | |
313 | Loader { |
314 | id: webappContainerWebViewLoader |
315 | + objectName: "containerWebviewLoader" |
316 | anchors.fill: parent |
317 | asynchronous: true |
318 | } |
319 | @@ -62,7 +64,8 @@ |
320 | , webappName: containerWebview.webappName |
321 | , webappUrlPatterns: containerWebview.webappUrlPatterns |
322 | , developerExtrasEnabled: containerWebview.developerExtrasEnabled |
323 | - , popupRedirectionUrlPrefix: containerWebview.popupRedirectionUrlPrefix}) |
324 | + , popupRedirectionUrlPrefixPattern: containerWebview.popupRedirectionUrlPrefixPattern |
325 | + , blockOpenExternalUrls: containerWebview.blockOpenExternalUrls}) |
326 | } |
327 | } |
328 | |
329 | |
330 | === modified file 'src/app/webcontainer/url-pattern-utils.cpp' |
331 | --- src/app/webcontainer/url-pattern-utils.cpp 2014-09-05 20:14:53 +0000 |
332 | +++ src/app/webcontainer/url-pattern-utils.cpp 2014-10-20 22:12:22 +0000 |
333 | @@ -21,6 +21,8 @@ |
334 | #include <QtCore/QRegularExpression> |
335 | #include <QDebug> |
336 | |
337 | +namespace |
338 | +{ |
339 | |
340 | /** |
341 | * Tests for the validity of a given webapp url pattern. It follows |
342 | @@ -35,7 +37,7 @@ |
343 | * @param pattern pattern that is to be tested for validity |
344 | * @return true if the url is valid, false otherwise |
345 | */ |
346 | -static bool isValidWebappUrlPattern(const QString& pattern) |
347 | +bool isValidWebappUrlPattern(const QString& pattern) |
348 | { |
349 | static QRegularExpression grammar("^http(s|s\\?)?://[^\\.]+\\.[^\\.\\*\\?]+\\.[^\\.\\*\\?]+(\\.[^\\.\\*\\?/]+)*/.*$"); |
350 | return grammar.match(pattern).hasMatch(); |
351 | @@ -71,7 +73,7 @@ |
352 | * @param pattern pattern that is to be tested for validity |
353 | * @return true if the url is valid, false otherwise |
354 | */ |
355 | -static bool isValidGoogleUrlPattern(const QString& pattern) |
356 | +bool isValidGoogleUrlPattern(const QString& pattern) |
357 | { |
358 | static QRegularExpression grammar("^http(s|s\\?)?://[^\\.\\?\\*]+\\.google\\.[^\\.\\?]+/.*$"); |
359 | return grammar.match(pattern).hasMatch(); |
360 | @@ -83,14 +85,31 @@ |
361 | * @param pattern pattern that is to be tested for validity |
362 | * @return true if the url is valid, false otherwise |
363 | */ |
364 | -static bool isValidStrictUrlPattern(const QString& pattern) |
365 | +bool isValidStrictUrlPattern(const QString& pattern) |
366 | { |
367 | static QRegularExpression grammar("^http(s|s\\?)?://[^\\.\\*\\?]+\\.[^\\.\\*\\?]+(\\.[^\\.\\*\\?/]+)*/.*$"); |
368 | return grammar.match(pattern).hasMatch(); |
369 | } |
370 | |
371 | |
372 | -QString UrlPatternUtils::transformWebappSearchPatternToSafePattern(const QString& pattern) |
373 | +QString toSafeHostnamePartPattern(const QString& hostnamePart) |
374 | +{ |
375 | + QString localHostnamePart = hostnamePart; |
376 | + return localHostnamePart.replace("*", "[^\\./]*"); |
377 | +} |
378 | + |
379 | +QString toSafeUrlPathPartPattern(const QString& urlPathPart) |
380 | +{ |
381 | + QString localUrlPathPart = urlPathPart; |
382 | + return localUrlPathPart.replace("*", "[^\\s]*"); |
383 | +} |
384 | + |
385 | +} // namespace { |
386 | + |
387 | + |
388 | +QString UrlPatternUtils::transformWebappSearchPatternToSafePattern( |
389 | + const QString& pattern, |
390 | + bool doTransformUrlPath) |
391 | { |
392 | QString transformedPattern; |
393 | |
394 | @@ -112,8 +131,10 @@ |
395 | // matches |
396 | // https?://*.ebay.com/* |
397 | QString scheme = match.captured(1); |
398 | - QString hostname = match.captured(2).replace("*", "[^\\./]*"); |
399 | - QString tail = match.captured(3).replace("*", "[^\\s]*"); |
400 | + QString hostname = toSafeHostnamePartPattern(match.captured(2)); |
401 | + QString tail = doTransformUrlPath ? |
402 | + toSafeUrlPathPartPattern(match.captured(3)) |
403 | + : match.captured(3); |
404 | |
405 | // reconstruct |
406 | transformedPattern = QString("%1%2%3").arg(scheme).arg(hostname).arg(tail); |
407 | @@ -128,7 +149,7 @@ |
408 | QString scheme = match.captured(1); |
409 | QString hostname = match.captured(2); |
410 | QString tld = match.captured(3).replace("*", "[^\\./]*"); |
411 | - QString tail = match.captured(4).replace("*", "[^\\s]*"); |
412 | + QString tail = toSafeUrlPathPartPattern(match.captured(4)); |
413 | |
414 | // reconstruct |
415 | transformedPattern = QString("%1%2%3%4") |
416 | |
417 | === modified file 'src/app/webcontainer/url-pattern-utils.h' |
418 | --- src/app/webcontainer/url-pattern-utils.h 2014-04-01 18:45:08 +0000 |
419 | +++ src/app/webcontainer/url-pattern-utils.h 2014-10-20 22:12:22 +0000 |
420 | @@ -25,7 +25,8 @@ |
421 | |
422 | namespace UrlPatternUtils { |
423 | |
424 | -QString transformWebappSearchPatternToSafePattern(const QString&); |
425 | +QString transformWebappSearchPatternToSafePattern(const QString& |
426 | + , bool doTransformUrlPath = true); |
427 | |
428 | QStringList filterAndTransformUrlPatterns(const QStringList & includePatterns); |
429 | |
430 | |
431 | === modified file 'src/app/webcontainer/webapp-container.cpp' |
432 | --- src/app/webcontainer/webapp-container.cpp 2014-10-03 14:41:14 +0000 |
433 | +++ src/app/webcontainer/webapp-container.cpp 2014-10-20 22:12:22 +0000 |
434 | @@ -158,8 +158,15 @@ |
435 | |
436 | context->setContextProperty("webappContainerHelper", m_webappContainerHelper.data()); |
437 | |
438 | - if ( ! m_popupRedirectionUrlPrefix.isEmpty()) { |
439 | - m_window->setProperty("popupRedirectionUrlPrefix", m_popupRedirectionUrlPrefix); |
440 | + if ( ! m_popupRedirectionUrlPrefixPattern.isEmpty()) { |
441 | + const QString WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL_ENV_VAR = |
442 | + qgetenv("WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL"); |
443 | + m_window->setProperty( |
444 | + "popupRedirectionUrlPrefixPattern", |
445 | + WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL_ENV_VAR == "1" |
446 | + ? m_popupRedirectionUrlPrefixPattern |
447 | + : UrlPatternUtils::transformWebappSearchPatternToSafePattern( |
448 | + m_popupRedirectionUrlPrefixPattern, false)); |
449 | } |
450 | |
451 | if (!m_userAgentOverride.isEmpty()) { |
452 | @@ -172,16 +179,20 @@ |
453 | m_window->setProperty("webviewOverrideFile", QUrl::fromLocalFile(overrideFile.absoluteFilePath())); |
454 | } |
455 | |
456 | - // When a webapp is being launched by name, the URL is pulled from its 'homepage'. |
457 | - if (m_webappName.isEmpty()) { |
458 | - QList<QUrl> urls = this->urls(); |
459 | - if (!urls.isEmpty()) { |
460 | - m_window->setProperty("url", urls.last()); |
461 | - } else if (m_webappModelSearchPath.isEmpty()) { |
462 | - return false; |
463 | - } |
464 | - // Otherwise, assume that the homepage will come from a locally defined |
465 | - // webapp-properties.json file pulled from the webapp model element. |
466 | + const QString WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY_ENV_VAR = |
467 | + qgetenv("WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY"); |
468 | + if (WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY_ENV_VAR == "1") { |
469 | + m_window->setProperty("blockOpenExternalUrls", true); |
470 | + } |
471 | + |
472 | + QList<QUrl> urls = this->urls(); |
473 | + if (!urls.isEmpty()) { |
474 | + m_window->setProperty("url", urls.last()); |
475 | + } else if (m_webappModelSearchPath.isEmpty()) { |
476 | + // Either we have a command line argument for the start URL or we have |
477 | + // local search path for a webapp definition (that would include in its |
478 | + // meta data a homepage). Any other case is faulty. |
479 | + return false; |
480 | } |
481 | |
482 | m_component->completeCreate(); |
483 | @@ -278,7 +289,7 @@ |
484 | } else if (argument == "--local-webapp-manifest") { |
485 | m_localWebappManifest = true; |
486 | } else if (argument.startsWith("--popup-redirection-url-prefix=")) { |
487 | - m_popupRedirectionUrlPrefix = argument.split("--popup-redirection-url-prefix=")[1]; |
488 | + m_popupRedirectionUrlPrefixPattern = argument.split("--popup-redirection-url-prefix=")[1]; |
489 | } else if (argument.startsWith("--local-cookie-db-path=")) { |
490 | m_localCookieStoreDbPath = argument.split("--local-cookie-db-path=")[1]; |
491 | } else if (argument.startsWith("--user-agent-string=")) { |
492 | |
493 | === modified file 'src/app/webcontainer/webapp-container.h' |
494 | --- src/app/webcontainer/webapp-container.h 2014-09-25 20:36:59 +0000 |
495 | +++ src/app/webcontainer/webapp-container.h 2014-10-20 22:12:22 +0000 |
496 | @@ -56,7 +56,7 @@ |
497 | bool m_backForwardButtonsVisible; |
498 | bool m_addressBarVisible; |
499 | bool m_localWebappManifest; |
500 | - QString m_popupRedirectionUrlPrefix; |
501 | + QString m_popupRedirectionUrlPrefixPattern; |
502 | QString m_localCookieStoreDbPath; |
503 | QString m_userAgentOverride; |
504 | QScopedPointer<WebappContainerHelper> m_webappContainerHelper; |
505 | |
506 | === modified file 'src/app/webcontainer/webapp-container.qml' |
507 | --- src/app/webcontainer/webapp-container.qml 2014-10-08 09:23:14 +0000 |
508 | +++ src/app/webcontainer/webapp-container.qml 2014-10-20 22:12:22 +0000 |
509 | @@ -39,10 +39,11 @@ |
510 | property var webappUrlPatterns |
511 | property bool oxide: false |
512 | property string accountProvider: "" |
513 | - property string popupRedirectionUrlPrefix: "" |
514 | + property string popupRedirectionUrlPrefixPattern: "" |
515 | property url webviewOverrideFile: "" |
516 | property var __webappCookieStore: null |
517 | property string localUserAgentOverride: "" |
518 | + property bool blockOpenExternalUrls: false |
519 | |
520 | contentOrientation: Screen.orientation |
521 | |
522 | @@ -77,10 +78,10 @@ |
523 | oxide: root.oxide |
524 | webappModelSearchPath: root.webappModelSearchPath |
525 | webappUrlPatterns: root.webappUrlPatterns |
526 | + blockOpenExternalUrls: root.blockOpenExternalUrls |
527 | |
528 | localUserAgentOverride: root.localUserAgentOverride |
529 | - |
530 | - popupRedirectionUrlPrefix: root.popupRedirectionUrlPrefix |
531 | + popupRedirectionUrlPrefixPattern: root.popupRedirectionUrlPrefixPattern |
532 | webviewOverrideFile: root.webviewOverrideFile |
533 | |
534 | anchors.fill: parent |
535 | @@ -107,7 +108,7 @@ |
536 | searchPath: root.webappModelSearchPath |
537 | |
538 | onModelContentChanged: { |
539 | - if (root.webappName) { |
540 | + if (root.webappName && root.url.length === 0) { |
541 | var idx = webappModel.getWebappIndex(root.webappName) |
542 | root.url = webappModel.data(idx, UnityWebApps.UnityWebappsAppModel.Homepage) |
543 | } |
544 | @@ -185,8 +186,22 @@ |
545 | browser.visible = true; |
546 | if (browser.currentWebview) { |
547 | browser.currentWebview.visible = true; |
548 | - browser.currentWebview.url = root.url |
549 | - browser.webappName = root.webappName |
550 | + browser.webappName = root.webappName; |
551 | + |
552 | + // As we use StateSaver to restore the URL, we need to check first if |
553 | + // it has not been set previously before setting the URL to the default property |
554 | + // homepage. |
555 | + var current_url = browser.currentWebview.url.toString(); |
556 | + if (!current_url || current_url.length === 0) { |
557 | + browser.currentWebview.url = root.url; |
558 | + } |
559 | + } |
560 | + } |
561 | + |
562 | + function updateBrowserUrl(url) { |
563 | + root.url = url; |
564 | + if (browser.currentWebview) { |
565 | + browser.currentWebview.url = url; |
566 | } |
567 | } |
568 | |
569 | @@ -205,11 +220,11 @@ |
570 | } |
571 | var requestedUrl = uris[0].toString(); |
572 | |
573 | - if (popupRedirectionUrlPrefix.length !== 0 |
574 | - && requestedUrl.indexOf(popupRedirectionUrlPrefix) === 0) { |
575 | + if (popupRedirectionUrlPrefixPattern.length !== 0 |
576 | + && requestedUrl.match(popupRedirectionUrlPrefixPattern)) { |
577 | return; |
578 | } |
579 | - browser.currentWebview.url = requestedUrl; |
580 | + updateBrowserUrl(requestedUrl); |
581 | } |
582 | } |
583 | } |
584 | |
585 | === modified file 'tests/autopilot/webapp_container/tests/__init__.py' |
586 | --- tests/autopilot/webapp_container/tests/__init__.py 2014-07-17 11:08:58 +0000 |
587 | +++ tests/autopilot/webapp_container/tests/__init__.py 2014-10-20 22:12:22 +0000 |
588 | @@ -20,6 +20,8 @@ |
589 | |
590 | from autopilot.testcase import AutopilotTestCase |
591 | from autopilot.platform import model |
592 | +from testtools.matchers import Equals |
593 | +from autopilot.matchers import Eventually |
594 | |
595 | from ubuntuuitoolkit import emulators as toolkit_emulators |
596 | from webapp_container.tests import fake_servers |
597 | @@ -38,16 +40,24 @@ |
598 | |
599 | |
600 | class WebappContainerTestCaseBase(AutopilotTestCase): |
601 | + def setUp(self): |
602 | + self.pointing_device = toolkit_emulators.get_pointing_device() |
603 | + super(WebappContainerTestCaseBase, self).setUp() |
604 | + |
605 | def get_webcontainer_app_path(self): |
606 | if os.path.exists(LOCAL_BROWSER_CONTAINER_PATH_NAME): |
607 | return LOCAL_BROWSER_CONTAINER_PATH_NAME |
608 | return INSTALLED_BROWSER_CONTAINER_PATH_NAME |
609 | |
610 | - def launch_webcontainer_app(self, args): |
611 | + def launch_webcontainer_app(self, args, envvars={}): |
612 | if model() != 'Desktop': |
613 | args.append( |
614 | '--desktop_file_hint=/usr/share/applications/' |
615 | 'webbrowser-app.desktop') |
616 | + if envvars: |
617 | + for envvar_key in envvars: |
618 | + self.patch_environment(envvar_key, envvars[envvar_key]) |
619 | + |
620 | try: |
621 | self.app = self.launch_test_application( |
622 | self.get_webcontainer_app_path(), |
623 | @@ -68,15 +78,43 @@ |
624 | def get_webcontainer_chrome(self): |
625 | return self.app.select_single("Chrome") |
626 | |
627 | + def get_webview(self): |
628 | + return self.app.select_single(objectName="webview") |
629 | + |
630 | + def get_oxide_webview(self): |
631 | + container = self.get_webview().select_single( |
632 | + objectName='containerWebviewLoader') |
633 | + return container.select_single('WebViewImplOxide') |
634 | + |
635 | + def assert_page_eventually_loaded(self, url): |
636 | + webview = self.get_oxide_webview() |
637 | + self.assertThat(webview.url, Eventually(Equals(url))) |
638 | + # loadProgress == 100 ensures that a page has actually loaded |
639 | + self.assertThat(webview.loadProgress, |
640 | + Eventually(Equals(100), timeout=20)) |
641 | + self.assertThat(webview.loading, Eventually(Equals(False))) |
642 | + |
643 | + def browse_to(self, url): |
644 | + webview = self.get_oxide_webview() |
645 | + webview.url = url |
646 | + self.assert_page_eventually_loaded(url) |
647 | + |
648 | |
649 | class WebappContainerTestCaseWithLocalContentBase(WebappContainerTestCaseBase): |
650 | + BASE_URL_SCHEME = 'http://' |
651 | + |
652 | def setUp(self): |
653 | super(WebappContainerTestCaseWithLocalContentBase, self).setUp() |
654 | self.http_server = fake_servers.WebappContainerContentHttpServer() |
655 | self.addCleanup(self.http_server.shutdown) |
656 | - self.base_url = "http://localhost:{}".format(self.http_server.port) |
657 | - |
658 | - def launch_webcontainer_app_with_local_http_server(self, args, path='/'): |
659 | + self.base_url = "{}localhost:{}".format( |
660 | + self.BASE_URL_SCHEME, self.http_server.port) |
661 | + |
662 | + def get_base_url_hostname(self): |
663 | + return self.base_url[len(self.BASE_URL_SCHEME):] |
664 | + |
665 | + def launch_webcontainer_app_with_local_http_server( |
666 | + self, args, path='/', envvars={}): |
667 | self.url = self.base_url + path |
668 | args.append(self.url) |
669 | - self.launch_webcontainer_app(args) |
670 | + self.launch_webcontainer_app(args, envvars) |
671 | |
672 | === modified file 'tests/autopilot/webapp_container/tests/fake_servers.py' |
673 | --- tests/autopilot/webapp_container/tests/fake_servers.py 2014-04-24 10:50:42 +0000 |
674 | +++ tests/autopilot/webapp_container/tests/fake_servers.py 2014-10-20 22:12:22 +0000 |
675 | @@ -26,14 +26,28 @@ |
676 | self.end_headers() |
677 | self.wfile.write(content.encode()) |
678 | |
679 | - def basic_html_content(self): |
680 | - return """ |
681 | -<html> |
682 | -<head> |
683 | -<title>Some content</title> |
684 | -</head> |
685 | -<body> |
686 | -This is some content |
687 | + def basic_html_content(self, content="basic"): |
688 | + return """ |
689 | +<html> |
690 | +<head> |
691 | +<title>Some content</title> |
692 | +</head> |
693 | +<body> |
694 | +This is some {} content |
695 | +</body> |
696 | +</html> |
697 | + """.format(content) |
698 | + |
699 | + def redirect_html_content(self): |
700 | + return """ |
701 | +<html> |
702 | +<head> |
703 | +<title>Some content</title> |
704 | +</head> |
705 | +<body> |
706 | +<div><a href='/redirect?url=myredirect&s=1&r=2' target='_blank'> |
707 | +<div style="height: 100%; width: 100%"></div> |
708 | +</a></div> |
709 | </body> |
710 | </html> |
711 | """ |
712 | @@ -42,6 +56,12 @@ |
713 | if self.path == '/': |
714 | self.send_response(200) |
715 | self.serve_content(self.basic_html_content()) |
716 | + elif self.path == '/other': |
717 | + self.send_response(200) |
718 | + self.serve_content(self.basic_html_content("other")) |
719 | + elif self.path == '/get-redirect': |
720 | + self.send_response(200) |
721 | + self.serve_content(self.redirect_html_content()) |
722 | else: |
723 | self.send_error(404) |
724 | |
725 | |
726 | === modified file 'tests/autopilot/webapp_container/tests/test_app_launch.py' |
727 | --- tests/autopilot/webapp_container/tests/test_app_launch.py 2014-07-17 11:08:58 +0000 |
728 | +++ tests/autopilot/webapp_container/tests/test_app_launch.py 2014-10-20 22:12:22 +0000 |
729 | @@ -23,7 +23,7 @@ |
730 | WebappContainerTestCaseWithLocalContentBase): |
731 | |
732 | def test_container_does_not_load_with_no_webapp_name_and_url(self): |
733 | - args = ['--webapp'] |
734 | + args = [] |
735 | self.launch_webcontainer_app(args) |
736 | self.assertIsNone(self.get_webcontainer_proxy()) |
737 | |
738 | |
739 | === added file 'tests/autopilot/webapp_container/tests/test_redirection_pattern.py' |
740 | --- tests/autopilot/webapp_container/tests/test_redirection_pattern.py 1970-01-01 00:00:00 +0000 |
741 | +++ tests/autopilot/webapp_container/tests/test_redirection_pattern.py 2014-10-20 22:12:22 +0000 |
742 | @@ -0,0 +1,59 @@ |
743 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
744 | +# Copyright 2014 Canonical |
745 | +# |
746 | +# This program is free software: you can redistribute it and/or modify it |
747 | +# under the terms of the GNU General Public License version 3, as published |
748 | +# by the Free Software Foundation. |
749 | +# |
750 | +# This program is distributed in the hope that it will be useful, |
751 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
752 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
753 | +# GNU General Public License for more details. |
754 | +# |
755 | +# You should have received a copy of the GNU General Public License |
756 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
757 | + |
758 | +from testtools.matchers import Equals |
759 | +from autopilot.matchers import Eventually |
760 | + |
761 | +from webapp_container.tests import WebappContainerTestCaseWithLocalContentBase |
762 | + |
763 | + |
764 | +class WebappContainerRedirectionPatternTestCase( |
765 | + WebappContainerTestCaseWithLocalContentBase): |
766 | + |
767 | + def test_browse_to_redirection_pattern_url(self): |
768 | + REDIRECTION_HOSTNAME = self.get_base_url_hostname() |
769 | + args = ["--popup-redirection-url-prefix={}{}{}".format( |
770 | + 'http://', REDIRECTION_HOSTNAME.replace('.', '\.'), |
771 | + '/redirect\\?url=([^&]*).*')] |
772 | + self.launch_webcontainer_app_with_local_http_server( |
773 | + args, |
774 | + '/get-redirect', |
775 | + {'WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY': '1', |
776 | + 'WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL': '1'}) |
777 | + self.get_webcontainer_window().visible.wait_for(True) |
778 | + |
779 | + webview = self.get_oxide_webview() |
780 | + external_open_watcher = webview.watch_signal( |
781 | + 'openExternalUrlTriggered(QString)') |
782 | + got_redirection_url_watcher = webview.watch_signal( |
783 | + 'gotRedirectionUrl(QString)') |
784 | + |
785 | + self.assertThat(external_open_watcher.was_emitted, Equals(False)) |
786 | + self.assertThat(got_redirection_url_watcher.was_emitted, Equals(False)) |
787 | + self.browse_to( |
788 | + "http://{}/get-redirect".format(REDIRECTION_HOSTNAME)) |
789 | + |
790 | + self.pointing_device.click_object(webview) |
791 | + |
792 | + self.assertThat( |
793 | + lambda: got_redirection_url_watcher.was_emitted, |
794 | + Eventually(Equals(True))) |
795 | + self.assertThat( |
796 | + webview.get_signal_emissions( |
797 | + 'gotRedirectionUrl(QString)')[0][0], |
798 | + Equals('myredirect')) |
799 | + self.assertThat( |
800 | + lambda: external_open_watcher.was_emitted, |
801 | + Eventually(Equals(True))) |
802 | |
803 | === modified file 'tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp' |
804 | --- tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp 2014-09-05 20:14:53 +0000 |
805 | +++ tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp 2014-10-20 22:12:22 +0000 |
806 | @@ -33,25 +33,32 @@ |
807 | { |
808 | QTest::addColumn<QString>("pattern"); |
809 | QTest::addColumn<QString>("transformedPattern"); |
810 | + QTest::addColumn<bool>("doTransformUrlPath"); |
811 | |
812 | // regular patterns |
813 | |
814 | QTest::newRow("Valid pattern") |
815 | << "https?://*.mydomain.com/*" |
816 | - << "https?://[^\\./]*.mydomain.com/[^\\s]*"; |
817 | + << "https?://[^\\./]*.mydomain.com/[^\\s]*" |
818 | + << true; |
819 | + |
820 | + QTest::newRow("Valid pattern with no tail replacement") |
821 | + << "https?://*.mydomain.com/l.php\\?\\w+=([^&]+).*" |
822 | + << "https?://[^\\./]*.mydomain.com/l.php\\?\\w+=([^&]+).*" |
823 | + << false; |
824 | |
825 | QTest::newRow("Valid pattern - short url") |
826 | << "https?://mydomain.com/*" |
827 | - << "https?://mydomain.com/[^\\s]*"; |
828 | + << "https?://mydomain.com/[^\\s]*" << true; |
829 | |
830 | QTest::newRow("Valid pattern - strict url") |
831 | << "https?://www.mydomain.com/*" |
832 | - << "https?://www.mydomain.com/[^\\s]*"; |
833 | + << "https?://www.mydomain.com/[^\\s]*" << true; |
834 | |
835 | #define WEBAPP_INVALID_URL_PATTERN_TEST(id,invalid_url_pattern) \ |
836 | QTest::newRow("Invalid pattern " #id) \ |
837 | << invalid_url_pattern \ |
838 | - << QString() |
839 | + << QString() << true |
840 | |
841 | WEBAPP_INVALID_URL_PATTERN_TEST(1, "http"); |
842 | WEBAPP_INVALID_URL_PATTERN_TEST(2, "://"); |
843 | @@ -74,16 +81,16 @@ |
844 | |
845 | QTest::newRow("Valid Google pattern") |
846 | << "https?://mail.google.*/*" |
847 | - << "https?://mail.google.[^\\./]*/[^\\s]*"; |
848 | + << "https?://mail.google.[^\\./]*/[^\\s]*" << true; |
849 | |
850 | QTest::newRow("Valid non Google pattern") |
851 | << "https://*.google.com/*" |
852 | - << "https://[^\\./]*.google.com/[^\\s]*"; |
853 | + << "https://[^\\./]*.google.com/[^\\s]*" << true; |
854 | |
855 | #define WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(id,invalid_google_url_pattern) \ |
856 | QTest::newRow("Invalid Google App pattern " #id) \ |
857 | << invalid_google_url_pattern \ |
858 | - << QString() |
859 | + << QString() << true |
860 | |
861 | WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(1, "https://*.google.*/*"); |
862 | WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(2, "https://service.gooo*gle.com/*"); |
863 | @@ -99,7 +106,8 @@ |
864 | { |
865 | QFETCH(QString, pattern); |
866 | QFETCH(QString, transformedPattern); |
867 | - QCOMPARE(UrlPatternUtils::transformWebappSearchPatternToSafePattern(pattern), transformedPattern); |
868 | + QFETCH(bool, doTransformUrlPath); |
869 | + QCOMPARE(UrlPatternUtils::transformWebappSearchPatternToSafePattern(pattern, doTransformUrlPath), transformedPattern); |
870 | } |
871 | |
872 | void filteredUrlPatterns_data() |
FAILED: Continuous integration, rev:750 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 1146/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/5607 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 3970 jenkins. qa.ubuntu. com/job/ webbrowser- app-utopic- amd64-ci/ 345 jenkins. qa.ubuntu. com/job/ webbrowser- app-utopic- armhf-ci/ 345 jenkins. qa.ubuntu. com/job/ webbrowser- app-utopic- armhf-ci/ 345/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ webbrowser- app-utopic- i386-ci/ 345 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/5297 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/6859 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/6859/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 14278 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-utopic/ 3343 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/4297 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/4297/ artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 1146/rebuild
http://