Merge lp:~uriboni/webbrowser-app/undo-close-tab into lp:webbrowser-app
- undo-close-tab
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Olivier Tilloy | ||||
Approved revision: | 1273 | ||||
Merged at revision: | 1271 | ||||
Proposed branch: | lp:~uriboni/webbrowser-app/undo-close-tab | ||||
Merge into: | lp:webbrowser-app | ||||
Diff against target: |
423 lines (+173/-46) 6 files modified
src/app/webbrowser/Browser.qml (+36/-0) src/app/webbrowser/Chrome.qml (+2/-0) src/app/webbrowser/TabsBar.qml (+3/-11) tests/autopilot/webbrowser_app/tests/test_keyboard.py (+4/-4) tests/autopilot/webbrowser_app/tests/test_tabs.py (+104/-16) tests/unittests/qml/tst_TabsBar.qml (+24/-15) |
||||
To merge this branch: | bzr merge lp:~uriboni/webbrowser-app/undo-close-tab | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Olivier Tilloy | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+275849@code.launchpad.net |
Commit message
Add keyboard shortcuts to undo closing tabs (Ctrl+Shift+T and Ctrl+Shift+W).
Description of the change
Add keyboard shortcut to undo closing tabs (ctrl+shift+w)
- 1260. By Ugo Riboni
-
Exclude the new tab view from being part of the undo logic
Olivier Tilloy (osomon) wrote : | # |
Olivier Tilloy (osomon) wrote : | # |
Also, Ctrl+Shift+W exit the application in chromium and firefox on desktop. For consistency with the competition, can we use Ctrl+Shift+T ?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1260
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1261. By Ugo Riboni
-
Should work also with the tabs list
- 1262. By Ugo Riboni
-
Fix tab close unit tests
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1262
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1263. By Ugo Riboni
-
Restore the whole state of the tab, not just its url, when undoing close
- 1264. By Ugo Riboni
-
Exclude incognito mode from the whole undo behavior
- 1265. By Ugo Riboni
-
Add AP test to verify incognito mode behavior
- 1266. By Ugo Riboni
-
Restore tabs to their previous index. Adjust AP tests.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1265
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1266
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1267. By Ugo Riboni
-
Add Ctrl+Shift+T as shortcut, since other major browsers have that
- 1268. By Ugo Riboni
-
Ensure that "new tab view" tabs do not get saved and restored
Ugo Riboni (uriboni) wrote : | # |
Note: in the bug report both CTRL+SHIFT+T (as firefox and chrome do) and CTRL+SHIFT+W (to complement CTRL+W to close a tab) were suggested as shortcuts. I implemented both because I think they both make sense.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1268
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
Incognito tabs are incorrectly being remembered: launch the browser, switch to private browsing, browse to a given page, close it with Ctrl+W, this switches back to public browsing, then press Ctrl+Shift+T: the private tab you just closed is being restored, as a public one.
- 1269. By Ugo Riboni
-
Make sure that closing the last tab in incognito mode does not remember it. Adjust AP tests to verify.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1269
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
In test_undo_
- 1270. By Ugo Riboni
-
Improve AP test to make sure we are not restoring tabs from incognito when exiting incognito, and to be a little bit more confident that there is no way to restore tabs when within incognito mode.
- 1271. By Ugo Riboni
-
Merge changes from trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1270
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
At least the following two tests are failing on my desktop:
webbrowser_
webbrowser_
It looks like Ctrl+T doesn’t work any longer to open a new tab (at least in the tests, it seems to work fine when I run the app).
Olivier Tilloy (osomon) wrote : | # |
276 + return count;
Please remove the trailing semicolon, for consistency.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1271
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Ugo Riboni (uriboni) wrote : | # |
> At least the following two tests are failing on my desktop:
>
> webbrowser_
> webbrowser_
>
> It looks like Ctrl+T doesn’t work any longer to open a new tab (at least in
> the tests, it seems to work fine when I run the app).
We had the same problem in the qml-tabs-model MR, and I fixed the problem already there. Given that this code presumably will go in the same silo, and that CI seems to be happy about the tests anyway (why ?), can we avoid fixing this here too and then having to solve the conflict ?
- 1272. By Ugo Riboni
-
Style: remove trailing semicolon
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1272
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
> We had the same problem in the qml-tabs-model MR, and I fixed the
> problem already there. Given that this code presumably will go in the
> same silo, and that CI seems to be happy about the tests anyway
> (why ?), can we avoid fixing this here too and then having to solve
> the conflict ?
Nothing guarantees that this will go in the same silo as the qml-tabs-model MR (especially so close to the code freeze for OTA-8). Branches should be mergeable on their own, unless one has a hard dependency on another one (but this is not the case here).
CI didn’t complain because it doesn’t run autopilot tests on desktop, only on a phone. I’ve been bugging the CI team about that, but without success so far. Until we get automated CI for desktop, we’ll need to run the tests ourselves manually to ensure they pass everywhere.
- 1273. By Ugo Riboni
-
Fix AP tests by keeping in mind that when calling press_key the case of the letter keys is significant (uppercase triggers Shift implicitly)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1273
http://
Executed test runs:
ABORTED: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Francis Ginther (fginther) wrote : | # |
I've restarted this MP to work around an issue triggering generic-
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1273
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
Looks good to me now, thanks.
Preview Diff
1 | === modified file 'src/app/webbrowser/Browser.qml' |
2 | --- src/app/webbrowser/Browser.qml 2015-11-03 11:56:01 +0000 |
3 | +++ src/app/webbrowser/Browser.qml 2015-11-09 10:55:44 +0000 |
4 | @@ -376,6 +376,7 @@ |
5 | } |
6 | |
7 | onRequestNewTab: browser.openUrlInNewTab("", makeCurrent, true, index) |
8 | + onTabClosed: internal.closeTab(index) |
9 | |
10 | onFindInPageModeChanged: { |
11 | if (!chrome.findInPageMode) internal.resetFocus() |
12 | @@ -1285,6 +1286,7 @@ |
13 | |
14 | QtObject { |
15 | id: internal |
16 | + property var closedTabHistory: [] |
17 | |
18 | function getOpenPages() { |
19 | var urls = []; |
20 | @@ -1325,8 +1327,19 @@ |
21 | } |
22 | |
23 | function closeTab(index) { |
24 | + // Save the incognito state before removing the tab, because |
25 | + // removing the last tab in the model will switch out incognito |
26 | + // mode, thus causing the check below to fail and save the tab |
27 | + // into the undo stack when it should be forgotten instead. |
28 | + var wasIncognito = incognito |
29 | var tab = tabsModel.remove(index) |
30 | if (tab) { |
31 | + if (!wasIncognito && tab.url.toString().length > 0) { |
32 | + closedTabHistory.push({ |
33 | + state: session.serializeTabState(tab), |
34 | + index: index |
35 | + }) |
36 | + } |
37 | tab.close() |
38 | } |
39 | if (tabsModel.count === 0) { |
40 | @@ -1341,6 +1354,14 @@ |
41 | } |
42 | } |
43 | |
44 | + function undoCloseTab() { |
45 | + if (!incognito && closedTabHistory.length > 0) { |
46 | + var tabInfo = closedTabHistory.pop() |
47 | + var tab = session.createTabFromState(tabInfo.state) |
48 | + internal.addTab(tab, true, tabInfo.index) |
49 | + } |
50 | + } |
51 | + |
52 | function switchToPreviousTab() { |
53 | if (browser.wide) { |
54 | internal.switchToTab((tabsModel.currentIndex - 1 + tabsModel.count) % tabsModel.count) |
55 | @@ -1713,6 +1734,21 @@ |
56 | onTriggered: internal.switchToPreviousTab() |
57 | } |
58 | |
59 | + // Ctrl+Shift+W or Ctrl+Shift+T: Undo close tab |
60 | + KeyboardShortcut { |
61 | + modifiers: Qt.ControlModifier | Qt.ShiftModifier |
62 | + key: Qt.Key_W |
63 | + enabled: chrome.visible || recentView.visible |
64 | + onTriggered: internal.undoCloseTab() |
65 | + } |
66 | + |
67 | + KeyboardShortcut { |
68 | + modifiers: Qt.ControlModifier | Qt.ShiftModifier |
69 | + key: Qt.Key_T |
70 | + enabled: chrome.visible || recentView.visible |
71 | + onTriggered: internal.undoCloseTab() |
72 | + } |
73 | + |
74 | // Ctrl+W or Ctrl+F4: Close the current tab |
75 | KeyboardShortcut { |
76 | modifiers: Qt.ControlModifier |
77 | |
78 | === modified file 'src/app/webbrowser/Chrome.qml' |
79 | --- src/app/webbrowser/Chrome.qml 2015-09-23 18:43:10 +0000 |
80 | +++ src/app/webbrowser/Chrome.qml 2015-11-09 10:55:44 +0000 |
81 | @@ -40,6 +40,7 @@ |
82 | readonly property alias bookmarkTogglePlaceHolder: navigationBar.bookmarkTogglePlaceHolder |
83 | |
84 | signal requestNewTab(int index, bool makeCurrent) |
85 | + signal tabClosed(int index) |
86 | |
87 | backgroundColor: incognito ? UbuntuColors.darkGrey : "#bcbcbc" |
88 | |
89 | @@ -68,6 +69,7 @@ |
90 | model: tabsModel |
91 | incognito: chrome.incognito |
92 | onRequestNewTab: chrome.requestNewTab(index, makeCurrent) |
93 | + onTabClosed: chrome.tabClosed(index) |
94 | } |
95 | |
96 | anchors { |
97 | |
98 | === modified file 'src/app/webbrowser/TabsBar.qml' |
99 | --- src/app/webbrowser/TabsBar.qml 2015-09-24 14:07:47 +0000 |
100 | +++ src/app/webbrowser/TabsBar.qml 2015-11-09 10:55:44 +0000 |
101 | @@ -33,6 +33,7 @@ |
102 | property bool incognito: false |
103 | |
104 | signal requestNewTab(int index, bool makeCurrent) |
105 | + signal tabClosed(int index) |
106 | |
107 | MouseArea { |
108 | anchors.fill: parent |
109 | @@ -94,7 +95,7 @@ |
110 | Action { |
111 | objectName: "tab_action_close_tab" |
112 | text: i18n.tr("Close Tab") |
113 | - onTriggered: internal.closeTab(menu.targetIndex) |
114 | + onTriggered: root.tabClosed(menu.targetIndex) |
115 | } |
116 | } |
117 | } |
118 | @@ -150,7 +151,7 @@ |
119 | |
120 | rightMargin: tabDelegate.rightMargin |
121 | |
122 | - onClosed: internal.closeTab(index) |
123 | + onClosed: root.tabClosed(index) |
124 | onSelected: root.model.currentIndex = index |
125 | onContextMenu: PopupUtils.open(contextualOptionsComponent, tabDelegate, {"targetIndex": index}) |
126 | } |
127 | @@ -181,13 +182,4 @@ |
128 | } |
129 | } |
130 | } |
131 | - |
132 | - QtObject { |
133 | - id: internal |
134 | - |
135 | - function closeTab(index) { |
136 | - var tab = root.model.remove(index) |
137 | - if (tab) tab.close() |
138 | - } |
139 | - } |
140 | } |
141 | |
142 | === modified file 'tests/autopilot/webbrowser_app/tests/test_keyboard.py' |
143 | --- tests/autopilot/webbrowser_app/tests/test_keyboard.py 2015-10-16 15:29:02 +0000 |
144 | +++ tests/autopilot/webbrowser_app/tests/test_keyboard.py 2015-11-09 10:55:44 +0000 |
145 | @@ -67,7 +67,7 @@ |
146 | self.address_bar = self.main_window.address_bar |
147 | |
148 | def open_tab(self, url): |
149 | - self.main_window.press_key('Ctrl+T') |
150 | + self.main_window.press_key('Ctrl+t') |
151 | new_tab_view = self.main_window.get_new_tab_view() |
152 | self.address_bar.go_to_url(url) |
153 | new_tab_view.wait_until_destroyed() |
154 | @@ -86,7 +86,7 @@ |
155 | Eventually(Equals(url))) |
156 | |
157 | def test_new_tab(self): |
158 | - self.main_window.press_key('Ctrl+T') |
159 | + self.main_window.press_key('Ctrl+t') |
160 | |
161 | webview = self.main_window.get_current_webview() |
162 | self.assertThat(webview.url, Equals("")) |
163 | @@ -306,7 +306,7 @@ |
164 | bookmarks_view = self.main_window.get_bookmarks_view() |
165 | self.assertThat(bookmarks_view.activeFocus, Eventually(Equals(True))) |
166 | |
167 | - self.main_window.press_key('Ctrl+T') |
168 | + self.main_window.press_key('Ctrl+t') |
169 | bookmarks_view.wait_until_destroyed() |
170 | |
171 | new_tab_view = self.main_window.get_new_tab_view() |
172 | @@ -339,7 +339,7 @@ |
173 | history_view = self.main_window.get_history_view() |
174 | self.assertThat(history_view.activeFocus, Eventually(Equals(True))) |
175 | |
176 | - self.main_window.press_key('Ctrl+T') |
177 | + self.main_window.press_key('Ctrl+t') |
178 | history_view.wait_until_destroyed() |
179 | |
180 | new_tab_view = self.main_window.get_new_tab_view() |
181 | |
182 | === modified file 'tests/autopilot/webbrowser_app/tests/test_tabs.py' |
183 | --- tests/autopilot/webbrowser_app/tests/test_tabs.py 2015-10-26 13:06:27 +0000 |
184 | +++ tests/autopilot/webbrowser_app/tests/test_tabs.py 2015-11-09 10:55:44 +0000 |
185 | @@ -18,6 +18,7 @@ |
186 | from autopilot.matchers import Eventually |
187 | from autopilot.platform import model |
188 | |
189 | +import time |
190 | import testtools |
191 | import unittest |
192 | |
193 | @@ -141,7 +142,7 @@ |
194 | the new page view""" |
195 | address_bar = self.main_window.address_bar |
196 | |
197 | - self.main_window.press_key('Ctrl+T') |
198 | + self.main_window.press_key('Ctrl+t') |
199 | self.assertThat(address_bar.activeFocus, Eventually(Equals(True))) |
200 | |
201 | self.main_window.press_key('Ctrl+Tab') |
202 | @@ -159,31 +160,31 @@ |
203 | allowing keyboard shortcuts to work without interruption""" |
204 | address_bar = self.main_window.address_bar |
205 | |
206 | - self.main_window.press_key('Ctrl+T') |
207 | - self.main_window.press_key('Ctrl+T') |
208 | + self.main_window.press_key('Ctrl+t') |
209 | + self.main_window.press_key('Ctrl+t') |
210 | url = self.base_url + "/test1" |
211 | self.main_window.go_to_url(url) |
212 | self.main_window.wait_until_page_loaded(url) |
213 | |
214 | - self.main_window.press_key('Ctrl+T') |
215 | + self.main_window.press_key('Ctrl+t') |
216 | url = self.base_url + "/test2" |
217 | self.main_window.go_to_url(url) |
218 | self.main_window.wait_until_page_loaded(url) |
219 | - self.main_window.press_key('Ctrl+T') |
220 | - self.main_window.press_key('Ctrl+T') |
221 | + self.main_window.press_key('Ctrl+t') |
222 | + self.main_window.press_key('Ctrl+t') |
223 | |
224 | - self.main_window.press_key('Ctrl+W') |
225 | + self.main_window.press_key('Ctrl+w') |
226 | self.assertThat(address_bar.activeFocus, Eventually(Equals(True))) |
227 | |
228 | - self.main_window.press_key('Ctrl+W') |
229 | - webview = self.main_window.get_current_webview() |
230 | - self.assertThat(webview.activeFocus, Eventually(Equals(True))) |
231 | - |
232 | - self.main_window.press_key('Ctrl+W') |
233 | - webview = self.main_window.get_current_webview() |
234 | - self.assertThat(webview.activeFocus, Eventually(Equals(True))) |
235 | - |
236 | - self.main_window.press_key('Ctrl+W') |
237 | + self.main_window.press_key('Ctrl+w') |
238 | + webview = self.main_window.get_current_webview() |
239 | + self.assertThat(webview.activeFocus, Eventually(Equals(True))) |
240 | + |
241 | + self.main_window.press_key('Ctrl+w') |
242 | + webview = self.main_window.get_current_webview() |
243 | + self.assertThat(webview.activeFocus, Eventually(Equals(True))) |
244 | + |
245 | + self.main_window.press_key('Ctrl+w') |
246 | self.assertThat(address_bar.activeFocus, Eventually(Equals(True))) |
247 | |
248 | |
249 | @@ -257,3 +258,90 @@ |
250 | webview.wait_until_destroyed() |
251 | self.assert_number_webviews_eventually(1) |
252 | self.main_window.get_new_tab_view() |
253 | + |
254 | + @testtools.skipIf(model() != "Desktop", "on desktop only") |
255 | + def test_undo_close_tab(self): |
256 | + tabs = self.main_window.chrome.get_tabs_bar() |
257 | + url0 = self.main_window.get_current_webview().url |
258 | + |
259 | + self.open_new_tab() |
260 | + url1 = self.base_url + "/tab/1" |
261 | + self.main_window.go_to_url(url1) |
262 | + self.main_window.wait_until_page_loaded(url1) |
263 | + self.assert_number_webviews_eventually(2) |
264 | + |
265 | + # Insert a "new tab view" page in the middle, without any page loaded |
266 | + # so that we can verify that it will not be restored |
267 | + self.open_new_tab() |
268 | + |
269 | + self.open_new_tab() |
270 | + url2 = self.base_url + "/tab/2" |
271 | + self.main_window.go_to_url(url2) |
272 | + self.main_window.wait_until_page_loaded(url2) |
273 | + self.assert_number_webviews_eventually(4) |
274 | + |
275 | + tabs.close_tab(3) |
276 | + self.assert_number_webviews_eventually(3) |
277 | + tabs.close_tab(2) |
278 | + self.assert_number_webviews_eventually(2) |
279 | + tabs.close_tab(1) |
280 | + self.assert_number_webviews_eventually(1) |
281 | + self.check_current_tab(url0) |
282 | + |
283 | + # Both ctrl+shift+w and ctrl+shift+t activate the undo, so test both |
284 | + self.main_window.press_key('Ctrl+Shift+w') |
285 | + self.assert_number_webviews_eventually(2) |
286 | + self.check_current_tab(url1) |
287 | + |
288 | + self.main_window.press_key('Ctrl+Shift+t') |
289 | + self.assert_number_webviews_eventually(3) |
290 | + self.check_current_tab(url2) |
291 | + |
292 | + self.main_window.press_key('Ctrl+Shift+t') |
293 | + self.assert_number_webviews_eventually(3) |
294 | + self.check_current_tab(url2) |
295 | + |
296 | + @testtools.skipIf(model() != "Desktop", "on desktop only") |
297 | + def test_undo_close_tab_incognito(self): |
298 | + start_url = self.main_window.get_current_webview().url |
299 | + self.open_new_tab() |
300 | + url = self.base_url + "/tab/1" |
301 | + self.main_window.go_to_url(url) |
302 | + self.main_window.wait_until_page_loaded(url) |
303 | + |
304 | + self.main_window.press_key('Ctrl+w') |
305 | + self.assert_number_webviews_eventually(1) |
306 | + self.check_current_tab(start_url) |
307 | + |
308 | + incognito_url = self.base_url + "/tab/2" |
309 | + self.main_window.enter_private_mode() |
310 | + self.assertThat(self.main_window.is_in_private_mode, |
311 | + Eventually(Equals(True))) |
312 | + self.main_window.go_to_url(incognito_url) |
313 | + self.main_window.wait_until_page_loaded(incognito_url) |
314 | + |
315 | + self.open_new_tab() |
316 | + self.main_window.go_to_url(incognito_url) |
317 | + self.main_window.wait_until_page_loaded(incognito_url) |
318 | + self.main_window.press_key('Ctrl+w') |
319 | + self.assert_number_incognito_webviews_eventually(1) |
320 | + |
321 | + # Test that no tabs will be restored in incognito mode. |
322 | + # We sleep for a bit after the keypress to give more confidence that |
323 | + # the tab still hasn't appeared within a reasonable amount of time. |
324 | + self.main_window.press_key('Ctrl+Shift+w') |
325 | + time.sleep(1) |
326 | + self.assert_number_incognito_webviews_eventually(1) |
327 | + |
328 | + # Close the last incognito tab to exit the mode. This is done on |
329 | + # purpose instead of using leave_private_mode since we want to |
330 | + # make sure the last tab is also not saved, as it is a corner case |
331 | + self.main_window.press_key('Ctrl+w') |
332 | + self.assertThat(self.main_window.is_in_private_mode, |
333 | + Eventually(Equals(False))) |
334 | + |
335 | + # Tabs that we closed before going incognito will be restored |
336 | + # when going back to default mode |
337 | + self.main_window.press_key('Ctrl+Shift+w') |
338 | + self.assert_number_webviews_eventually(2) |
339 | + self.check_current_tab(url) |
340 | |
341 | === modified file 'tests/unittests/qml/tst_TabsBar.qml' |
342 | --- tests/unittests/qml/tst_TabsBar.qml 2015-10-01 19:53:14 +0000 |
343 | +++ tests/unittests/qml/tst_TabsBar.qml 2015-11-09 10:55:44 +0000 |
344 | @@ -75,6 +75,12 @@ |
345 | } |
346 | |
347 | SignalSpy { |
348 | + id: tabClosedSpy |
349 | + target: tabs |
350 | + signalName: "tabClosed" |
351 | + } |
352 | + |
353 | + SignalSpy { |
354 | id: reloadSpy |
355 | target: root |
356 | signalName: "reload" |
357 | @@ -121,13 +127,16 @@ |
358 | } |
359 | newTabRequestSpy.clear() |
360 | reloadSpy.clear() |
361 | + tabClosedSpy.clear() |
362 | } |
363 | |
364 | function populateTabs() { |
365 | - for (var i = 0; i < 3; ++i) { |
366 | + var count = 3 |
367 | + for (var i = 0; i < count; ++i) { |
368 | tabs.appendTab("", "tab " + i, "") |
369 | } |
370 | - compare(tabsModel.currentIndex, 2) |
371 | + compare(tabsModel.currentIndex, count - 1) |
372 | + return count |
373 | } |
374 | |
375 | function test_create_new_tab() { |
376 | @@ -153,11 +162,11 @@ |
377 | |
378 | function test_mouse_middle_click() { |
379 | // Middle click closes the tab |
380 | - populateTabs() |
381 | - for (var i = 2; i >= 0; --i) { |
382 | - var tab0 = getTabDelegate(0) |
383 | - clickItem(tab0, Qt.MiddleButton) |
384 | - compare(tabsModel.count, i) |
385 | + var count = populateTabs() |
386 | + for (var i = 0; i < count; i++) { |
387 | + var tab = getTabDelegate(i) |
388 | + clickItem(tab, Qt.MiddleButton) |
389 | + compare(tabClosedSpy.count, i + 1) |
390 | } |
391 | } |
392 | |
393 | @@ -196,12 +205,13 @@ |
394 | } |
395 | |
396 | function test_close_tabs(data) { |
397 | - populateTabs() |
398 | - for (var i = 2; i >= 0; --i) { |
399 | - var tab0 = getTabDelegate(0) |
400 | - var closeButton = findChild(tab0, "closeButton") |
401 | + var count = populateTabs() |
402 | + for (var i = 0; i < count; i++) { |
403 | + var tab = getTabDelegate(count - (i + 1)) |
404 | + var closeButton = findChild(tab, "closeButton") |
405 | clickItem(closeButton, data.button) |
406 | - compare(tabsModel.count, i) |
407 | + compare(tabClosedSpy.count, i + 1) |
408 | + compare(tabClosedSpy.signalArguments[i][0], count - (i + 1)) |
409 | } |
410 | } |
411 | |
412 | @@ -261,9 +271,8 @@ |
413 | var menu = popupMenuOnTab(1) |
414 | var item = getMenuItemForAction(menu, "close_tab") |
415 | clickItem(item) |
416 | - compare(tabsModel.count, 2) |
417 | - compare(tabsModel.get(0).title, "tab 0") |
418 | - compare(tabsModel.get(1).title, "tab 2") |
419 | + compare(tabClosedSpy.count, 1) |
420 | + compare(tabClosedSpy.signalArguments[0][0], 1) |
421 | } |
422 | |
423 | function test_context_menu_reload() { |
As pointed out by mterry in https:/ /bugs.launchpad .net/ubuntu/ +source/ webbrowser- app/+bug/ 1499767/ comments/ 3, only saving/restoring the URL is not enough. We need to save and restore the full state of the webview, which includes back/forward history, current scroll offset, form data, … The Oxide WebView has a 'currentState' property that you can use.