Merge lp:~uriboni/webbrowser-app/new-tab-wide-format into lp:webbrowser-app

Proposed by Ugo Riboni
Status: Merged
Merged at revision: 1128
Proposed branch: lp:~uriboni/webbrowser-app/new-tab-wide-format
Merge into: lp:webbrowser-app
Diff against target: 1928 lines (+1244/-153)
21 files modified
debian/control (+1/-0)
src/app/webbrowser/Browser.qml (+63/-27)
src/app/webbrowser/DraggableUrlDelegateWide.qml (+98/-0)
src/app/webbrowser/NewTabViewWide.qml (+317/-0)
src/app/webbrowser/UrlDelegateWide.qml (+86/-0)
src/app/webbrowser/bookmarks-folder-model.cpp (+21/-1)
src/app/webbrowser/bookmarks-folder-model.h (+1/-0)
src/app/webbrowser/bookmarks-folderlist-model.cpp (+5/-0)
src/app/webbrowser/bookmarks-folderlist-model.h (+2/-0)
tests/autopilot/webbrowser_app/emulators/browser.py (+77/-4)
tests/autopilot/webbrowser_app/tests/__init__.py (+8/-2)
tests/autopilot/webbrowser_app/tests/test_addressbar_bookmark.py (+2/-6)
tests/autopilot/webbrowser_app/tests/test_bookmark_options.py (+32/-46)
tests/autopilot/webbrowser_app/tests/test_findinpage.py (+1/-2)
tests/autopilot/webbrowser_app/tests/test_new_tab_view.py (+121/-43)
tests/autopilot/webbrowser_app/tests/test_private.py (+8/-13)
tests/autopilot/webbrowser_app/tests/test_tabs.py (+2/-6)
tests/unittests/bookmarks-folder-model/tst_BookmarksFolderModelTests.cpp (+6/-3)
tests/unittests/qml/CMakeLists.txt (+9/-0)
tests/unittests/qml/tst_NewTabViewWide.qml (+372/-0)
tests/unittests/qml/tst_QmlTests.cpp (+12/-0)
To merge this branch: bzr merge lp:~uriboni/webbrowser-app/new-tab-wide-format
Reviewer Review Type Date Requested Status
Olivier Tilloy Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+266382@code.launchpad.net

Commit message

Implement the widescreen/landscape version of the "new tab" view.
This adds a build dependency on qml-module-qt-labs-settings (for unit tests).

Description of the change

Implement the widescreen/landscape version of the "new tab" view.

It requires the new Sections UITK component which is currently in the staging branch: lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/staging

To post a comment you must log in.
1075. By Ugo Riboni

Merge changes from trunk

1076. By Ugo Riboni

Remove useless import and fix flake8 errors

1077. By Ugo Riboni

Revert changes to UrlDelegate.qml as we are now using a new component instead

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1078. By Ugo Riboni

Fix copyright header

1079. By Ugo Riboni

Revert changes to UrlsList as we are not using it anymore

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1080. By Ugo Riboni

Add qt.labs.settings as build dep

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1081. By Ugo Riboni

Revert previous commit and actually commit the change to the debian dependencies

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

When scrolling the "top sites" view, the first item is drawn on top of the sections header. Either the header should have a higher z-order than the list view, or the list view should be clipped.

The background color of the sections header doesn’t match the visual spec (https://docs.google.com/presentation/d/1ggKmkxUFR5xCBcvkjJ4On9b4iKzEqcycz4hjc16tBGo/edit#slide=id.g2bddb9a1a_038).

In the bookmarks view, when the right panel has active focus the current folder in the left panel should still be highlighted.

In the bookmarks view, the font color for the current bookmark in the right panel shouldn’t be orange.

It seems to be that favicons in the view are too large, and that the font size for delegates is too big as well.

In the visual spec the folders list has a left margin, and folders are separated by horizontal lines.

According to the specification: « User can drag a bookmark in a folder. Bookmarks can only exist in one folder at a time ».

On my vivid desktop, with the UITK staging branch, QmlTests::NewTabLandscapeView::test_switch_sections_by_keyboard() is reliably failing:
  2: FAIL! : QmlTests::NewTabLandscapeView::test_switch_sections_by_keyboard() Compared values are not the same
  2: Actual (): 0
  2: Expected (): 1
  2: Loc: [/home/osomon/dev/phablet/browser/webbrowser-app/tests/unittests/qml/tst_NewTabLandscapeView.qml(191)]

Although not specified, there should probably be scrollbars for all the listviews.

Can you check with design whether we really want all the top sites section to not have a limit? I’d personally add a limit (maybe 10, or 20 top sites max).

Can NewTabLandscapeView be renamed NewTabViewWide?

review: Needs Fixing
1082. By Ugo Riboni

Move the Sections block to the bottom of the view so that list items will not overlap it

1083. By Ugo Riboni

Keep the current folder selected in orange even when the folder list does not have active focus

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1084. By Ugo Riboni

Rename the components to be called *Wide instead of *Landscape

1085. By Ugo Riboni

Add scrollbars to all lists

1086. By Ugo Riboni

Add a limit of 10 items to the top sites list and unit test it

Revision history for this message
Ugo Riboni (uriboni) wrote :

> When scrolling the "top sites" view, the first item is drawn on top of the
> sections header. Either the header should have a higher z-order than the list
> view, or the list view should be clipped.

Done

> The background color of the sections header doesn’t match the visual spec (htt
> ps://docs.google.com/presentation/d/1ggKmkxUFR5xCBcvkjJ4On9b4iKzEqcycz4hjc16tB
> Go/edit#slide=id.g2bddb9a1a_038).

This and all the other visuals-related comments you made refer to the above linked document, which is the UX spec, not the visual spec. The current design follows the visual spec as closely as possible (minus some changes that will come from the UITK): https://docs.google.com/presentation/d/1woHjO8K4iqyVZZlfQ4BXL0DhYbwkEmZ7wvcUhYzHDRk/edit?pli=1#slide=id.gb81843c7e_0_42

> According to the specification: « User can drag a bookmark in a folder.
> Bookmarks can only exist in one folder at a time ».

I consulted with design and they need to provide some extra UX and visual guidance. They will do so next week but in the meantime I am adding a provisional implementation based on advice I got from James over IRC.

> On my vivid desktop, with the UITK staging branch,
> QmlTests::NewTabLandscapeView::test_switch_sections_by_keyboard() is reliably
> failing:
> 2: FAIL! :
> QmlTests::NewTabLandscapeView::test_switch_sections_by_keyboard() Compared
> values are not the same
> 2: Actual (): 0
> 2: Expected (): 1
> 2: Loc: [/home/osomon/dev/phablet/browser/webbrowser-
> app/tests/unittests/qml/tst_NewTabLandscapeView.qml(191)]

This is caused by a recent change in the UITK staging branch. I submitted a bug to track it: https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1481233

> Although not specified, there should probably be scrollbars for all the
> listviews.

Done

> Can you check with design whether we really want all the top sites section to
> not have a limit? I’d personally add a limit (maybe 10, or 20 top sites max).

James suggested trying with a limit of 10. This is implemented now.

> Can NewTabLandscapeView be renamed NewTabViewWide?

Done

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1087. By Ugo Riboni

Implement a preliminary version of drag and drop support for reordering bookmarks between folders. Visual and UX design input missing so there are obvious placeholders.

1088. By Ugo Riboni

Merge changes from trunk

1089. By Ugo Riboni

Correctly honor draggable property

Revision history for this message
Olivier Tilloy (osomon) wrote :

Why is there a new "selectedIndexNewTabViewWide" setting? If, as I suspect, this is because the UX spec mandates that the state being retained, then it shouldn’t be a setting. Instead, the StateSaver should be used for that.

Favicons appear to be too large compared to the visual spec (hint: the Favicon component already has a built-in default size, you should probably not change it).

Folder names in bookmarks (left panel) shouldn’t be black when not selected, in the visual spec they appear to be darkGrey.

The spec doesn’t consider the case where a bookmark folder is empty. Can you check with design whether we should display some sort of informative message in this case, or if having an empty right panel is expected?

Can the failing unit test be temporarily skipped (http://doc.qt.io/qt-5/qml-qttest-testcase.html#skip-method) with a reference to bug #1481233 ?

If I swipe a bookmark to the right to delete it, the red delete action covers the left panel.

Bookmark dnd doesn’t seem to work here (I’m not seeing any icon appear when hovering over a bookmark). Might be due to me running a locally-built (and not installed) version of the UITK staging branch.

43 + Binding { target: newTabViewLoader.item; property: "focus"; value: newTabViewLoader.focus }
Is this really needed? A Loader is a FocusScope, so I would expect that always setting focus to true in the component being loaded would be enough to have focus handling just work.

Why was asynchronous loading removed from newTabViewLoader?

There’s now two strings for top sites: "Top Sites" and "Top sites". Can this be made consistent?

In bookmarks-folderlist-model.[h|cpp], I don’t think the count() method is necessary, you can simply define the getter for the count property to be rowCount(). And countChanged() doesn’t appear to ever be emitted, that seems wrong.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

I am now seeing the DND icon when hovering over a bookmark, and I can drag it and drop it in another folder, but this doesn’t appear to actually move it.

review: Needs Fixing
1090. By Ugo Riboni

Fix incorrect item reference that prevented dropping bookmarks to work

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

In debian/control, the build dependency and runtime dependency of webbrowser-app on qtdeclarative5-ubuntu-ui-toolkit-plugin need to specify that they require a version >= 1.3.

review: Needs Fixing
1091. By Ugo Riboni

Use default size for Favicons in delegates

1092. By Ugo Riboni

Adjust folder color to match visual spec

1093. By Ugo Riboni

More fixes on the drag and drop

1094. By Ugo Riboni

Clip the lists to prevent the slide-to-delete element to cover folders

1095. By Ugo Riboni

Remove unnecessary binding for keyboard focus

1096. By Ugo Riboni

Remove async loading on the new tab view loader as it was removed by mistake by original author of the branch

1097. By Ugo Riboni

Fix case of "top sites" string to match the non-widescreen version

1098. By Ugo Riboni

More properly implement the count property of the folder list model

1099. By Ugo Riboni

Rename the settings key used to store the default section to something more clear

1100. By Ugo Riboni

Clip list items instead of lists, so that we can still drag the items without having to reparent them to the outer view

1101. By Ugo Riboni

Fix unit tests broken by previous change

1102. By Ugo Riboni

Skip test that would fail due to UITK bug

1103. By Ugo Riboni

Add a (currently failing) unit test for drag and drop, and fix a mistake in how the drag start event was being emitted

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1104. By Ugo Riboni

Reimplement the drag and drop test as autopilot tests

Revision history for this message
Ugo Riboni (uriboni) wrote :

All other items that are not specifically mentioned here should have been fixed or addressed.

> Why is there a new "selectedIndexNewTabViewWide" setting? If, as I suspect,
> this is because the UX spec mandates that the state being retained, then it
> shouldn’t be a setting. Instead, the StateSaver should be used for that.

It needs a setting because the StateSaver won't save the state when closing the app normally, and we want to remember in which section to open the view by default regardless of how the app was closed.

> The spec doesn’t consider the case where a bookmark folder is empty. Can you
> check with design whether we should display some sort of informative message
> in this case, or if having an empty right panel is expected?

I had already asked some days ago. They are working on it AFAIK.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

If I swipe a bookmark to the right to delete it, hovering over it still displays the grip that allows dragging it to a different folder (partially clipped by the window). I would expect this grip to be disabled/hidden while awaiting confirmation of whether to delete or not.

If I open a new tab, then open the history view (either from the drawer menu or with Ctrl+H), then close it, the sections header’s rendering is busted (the background color is drawn, but not the sections). It appears to be a focus issue, as it fixes itself if I press twice the down arrow key to focus the view again. This doesn’t happen with e.g. the settings view.

As pointed out in an earlier comment, in debian/control, the build dependency and runtime dependency of webbrowser-app on qtdeclarative5-ubuntu-ui-toolkit-plugin need to specify that they require a version >= 1.3.

When running the autopilot tests on my vivid desktop with version 1.3 of the toolkit, I need to modify line 295 of tests/autopilot/webbrowser_app/emulators/browser.py to make the tests pass: s/Icon11/Icon/. I was told by Brendan earlier today that this is a recent change in autopilot, can you apply it in this branch and verify that CI is happy with it?

Even with the above fixed, I’m seeing 3 errors when running the autopilot tests for test_new_tab_view on my desktop:
  webbrowser_app.tests.test_new_tab_view.TestNewTabViewContents.test_open_top_site
  webbrowser_app.tests.test_new_tab_view.TestNewTabViewContents.test_default_home_bookmark
  webbrowser_app.tests.test_new_tab_view.TestNewTabViewContents.test_open_bookmark

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

Regarding drag and drop in unit tests: I just did a quick test, modifying test_drag() to do the following:

    function log_item_pos() { console.log("item.pos =", item.x, item.y) }
    log_item_pos()
    item.xChanged.connect(log_item_pos)
    item.yChanged.connect(log_item_pos)
    var c = centerOf(grip)
    mouseDrag(grip, c.x, c.y, -200, 100)

When running it, even though I’m not visualizing the item move, logging proves that it’s actually moving:

    qml: item.pos = 0 56
    qml: item.pos = -11 78
    qml: item.pos = -11 78
    qml: item.pos = -22 133
    qml: item.pos = -22 133
    qml: item.pos = -233 222
    qml: item.pos = -233 222
    qml: item.pos = 0 222
    qml: item.pos = 0 56

1105. By Ugo Riboni

Bump the UITK import version in debian/control

1106. By Ugo Riboni

Hide the dragging grip on bookmarks while the slide-to-delete action in progress

1107. By Ugo Riboni

Move some tests to the non-widescreen class only as the same tests are already implemented as unittests for the widescreen version and would fail in any case

1108. By Ugo Riboni

Fix a problem in how Icons are addressed in AP tests that was making some of them fail when using the uitk 1.3

1109. By Ugo Riboni

Prevent the Sections component to behave erratically when componets from 1.2 are imported while it is displayed. The real fix is to replace all imports to 1.3 but this suffices for now, while the work is being done in another branch.

Revision history for this message
Ugo Riboni (uriboni) wrote :

Fixed unless otherwise noted

> If I open a new tab, then open the history view (either from the drawer menu
> or with Ctrl+H), then close it, the sections header’s rendering is busted (the
> background color is drawn, but not the sections). It appears to be a focus
> issue, as it fixes itself if I press twice the down arrow key to focus the
> view again. This doesn’t happen with e.g. the settings view.

This is caused by the HistoryView importing Ubuntu.Components 1.2
According to the SDK team mixing imports seems to be not supported anymore. I fixed this only in HistoryView for now but the right thing to do would be to bump all imports to 1.3 to avoid other unexpected and hard to debug problems.

> When running the autopilot tests on my vivid desktop with version 1.3 of the
> toolkit, I need to modify line 295 of
> tests/autopilot/webbrowser_app/emulators/browser.py to make the tests pass:
> s/Icon11/Icon/. I was told by Brendan earlier today that this is a recent
> change in autopilot, can you apply it in this branch and verify that CI is
> happy with it?

Let's see what CI says.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1110. By Ugo Riboni

Merge changes from trunk

1111. By Ugo Riboni

Bump import to 2.4 in newly added unit test file

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

The 'inBookmarksView' property should be marked readonly.

Ctrl+Tab works to switch between sections, Tab doesn’t, even though there seems to be code for handling this (is it bug #1481233 ?).

If I cancel a drag (by dropping it somewhere it’s not accepted), it seems the bookmarks list’s interactivity is not restored (I cannot click and drag to move up/down the list).

review: Needs Fixing
1112. By Ugo Riboni

Merge changes from trunk

1113. By Ugo Riboni

Correctly mark a property as readonly

1114. By Ugo Riboni

Fix a bug preventing the interactivity in the boomarks list to be correctly restored at the end of a drag

Revision history for this message
Ugo Riboni (uriboni) wrote :

All fixed and yes, the problem with TAB is caused by bug #1481233

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1115. By Ugo Riboni

More fixes for correctly emitting the end of drag event

1116. By Ugo Riboni

Make it impossible to have keyboard focus within an empty list

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

I’m reliably getting 4 autopilot test failures on my desktop:

webbrowser_app.tests.test_private.TestPrivateView.test_url_showing_in_top_sites_in_and_out_private_mode
webbrowser_app.tests.test_bookmark_options.TestBookmarkOptions.test_save_bookmarked_url_in_new_folder
webbrowser_app.tests.test_bookmark_options.TestBookmarkOptions.test_save_bookmarked_url_in_existing_folder
webbrowser_app.tests.test_bookmark_options.TestBookmarkOptions.test_save_bookmarked_url_in_default_folder

review: Needs Fixing
1117. By Ugo Riboni

Fix some recent AP tests by smoothing away the differences between the wide and narrow new tab views via emulators and helper functions

1118. By Ugo Riboni

Remove method from main window emulator as it does not belong there

1119. By Ugo Riboni

Fix flake8

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

Still seeing 3 autopilot failures on desktop:

webbrowser_app.tests.test_bookmark_options.TestBookmarkOptions.test_save_bookmarked_url_in_existing_folder
webbrowser_app.tests.test_new_tab_view.TestNewTabViewContentsWide.test_remove_top_sites
webbrowser_app.tests.test_private.TestPrivateView.test_url_showing_in_top_sites_in_and_out_private_mode

review: Needs Fixing
1120. By Ugo Riboni

Refactor to fix a failing test

1121. By Ugo Riboni

Ensure correct section is always selected, not taking for granted the default

1122. By Ugo Riboni

More fixes for tests in narrow screen mode

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

This looks good now.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2015-08-11 11:18:36 +0000
+++ debian/control 2015-08-12 13:42:27 +0000
@@ -11,6 +11,7 @@
11 python3-all,11 python3-all,
12 python3-flake8,12 python3-flake8,
13 qml-module-qt-labs-folderlistmodel,13 qml-module-qt-labs-folderlistmodel,
14 qml-module-qt-labs-settings,
14 qml-module-qtquick2 (>= 5.4),15 qml-module-qtquick2 (>= 5.4),
15 qml-module-qttest,16 qml-module-qttest,
16 qt5-default,17 qt5-default,
1718
=== modified file 'src/app/webbrowser/Browser.qml'
--- src/app/webbrowser/Browser.qml 2015-08-11 10:37:56 +0000
+++ src/app/webbrowser/Browser.qml 2015-08-12 13:42:27 +0000
@@ -119,12 +119,14 @@
119 property string searchEngine: settingsDefaults.searchEngine119 property string searchEngine: settingsDefaults.searchEngine
120 property string allowOpenInBackgroundTab: settingsDefaults.allowOpenInBackgroundTab120 property string allowOpenInBackgroundTab: settingsDefaults.allowOpenInBackgroundTab
121 property bool restoreSession: settingsDefaults.restoreSession121 property bool restoreSession: settingsDefaults.restoreSession
122 property int newTabDefaultSection: settingsDefaults.newTabDefaultSection
122123
123 function restoreDefaults() {124 function restoreDefaults() {
124 homepage = settingsDefaults.homepage125 homepage = settingsDefaults.homepage
125 searchEngine = settingsDefaults.searchEngine126 searchEngine = settingsDefaults.searchEngine
126 allowOpenInBackgroundTab = settingsDefaults.allowOpenInBackgroundTab127 allowOpenInBackgroundTab = settingsDefaults.allowOpenInBackgroundTab
127 restoreSession = settingsDefaults.restoreSession128 restoreSession = settingsDefaults.restoreSession
129 newTabDefaultSection = settingsDefaults.newTabDefaultSection
128 }130 }
129 }131 }
130132
@@ -135,6 +137,7 @@
135 readonly property string searchEngine: "google"137 readonly property string searchEngine: "google"
136 readonly property string allowOpenInBackgroundTab: "default"138 readonly property string allowOpenInBackgroundTab: "default"
137 readonly property bool restoreSession: true139 readonly property bool restoreSession: true
140 readonly property int newTabDefaultSection: 0
138 }141 }
139142
140 FocusScope {143 FocusScope {
@@ -219,6 +222,7 @@
219 }222 }
220 }223 }
221 active: false224 active: false
225 asynchronous: true
222226
223 Connections {227 Connections {
224 target: browser228 target: browser
@@ -230,35 +234,61 @@
230 }234 }
231 }235 }
232236
233 sourceComponent: browser.incognito ? newPrivateTabViewComponent : newTabViewComponent237 sourceComponent: browser.incognito ? newPrivateTabView :
238 (browser.wide ? newTabViewWide : newTabView)
234239
235 Component {240 Component {
236 id: newTabViewComponent241 id: newTabView
237242
238 NewTabView {243 NewTabView {
239 historyModel: browser.historyModel244 anchors.fill: parent
240 bookmarksModel: browser.bookmarksModel245 historyModel: browser.historyModel
241 settingsObject: settings246 bookmarksModel: browser.bookmarksModel
242 onBookmarkClicked: {247 settingsObject: settings
243 chrome.requestedUrl = url248 focus: true
244 currentWebview.url = url249 onBookmarkClicked: {
245 tabContainer.forceActiveFocus()250 chrome.requestedUrl = url
246 }251 currentWebview.url = url
247 onBookmarkRemoved: browser.bookmarksModel.remove(url)252 tabContainer.forceActiveFocus()
248 onHistoryEntryClicked: {253 }
249 chrome.requestedUrl = url254 onBookmarkRemoved: browser.bookmarksModel.remove(url)
250 currentWebview.url = url255 onHistoryEntryClicked: {
251 tabContainer.forceActiveFocus()256 chrome.requestedUrl = url
252 }257 currentWebview.url = url
253 }258 tabContainer.forceActiveFocus()
254 }259 }
255260 }
256 Component {261 }
257 id: newPrivateTabViewComponent262
258263 Component {
259 NewPrivateTabView { }264 id: newTabViewWide
260 }265
261 asynchronous: true266 NewTabViewWide {
267 anchors.fill: parent
268 historyModel: browser.historyModel
269 bookmarksModel: browser.bookmarksModel
270 settingsObject: settings
271 focus: true
272 onBookmarkClicked: {
273 chrome.requestedUrl = url
274 currentWebview.url = url
275 tabContainer.forceActiveFocus()
276 }
277 onBookmarkRemoved: browser.bookmarksModel.remove(url)
278 onHistoryEntryClicked: {
279 chrome.requestedUrl = url
280 currentWebview.url = url
281 tabContainer.forceActiveFocus()
282 }
283 onReleasingKeyboardFocus: chrome.focus = true
284 }
285 }
286
287 Component {
288 id: newPrivateTabView
289
290 NewPrivateTabView { anchors.fill: parent }
291 }
262 }292 }
263293
264 SearchEngine {294 SearchEngine {
@@ -391,7 +421,13 @@
391 canSimplifyText: !browser.wide421 canSimplifyText: !browser.wide
392 editing: activeFocus || suggestionsList.activeFocus422 editing: activeFocus || suggestionsList.activeFocus
393423
394 Keys.onDownPressed: if (suggestionsList.count) suggestionsList.focus = true424 Keys.onDownPressed: {
425 if (suggestionsList.count) suggestionsList.focus = true
426 else if (newTabViewLoader.status == Loader.Ready) {
427 newTabViewLoader.focus = true
428 }
429 }
430
395 Keys.onEscapePressed: {431 Keys.onEscapePressed: {
396 if (chrome.findInPageMode) {432 if (chrome.findInPageMode) {
397 chrome.findInPageMode = false433 chrome.findInPageMode = false
@@ -1134,7 +1170,7 @@
1134 PopupUtils.open(bookmarkOptionsComponent,1170 PopupUtils.open(bookmarkOptionsComponent,
1135 chrome.bookmarkTogglePlaceHolder,1171 chrome.bookmarkTogglePlaceHolder,
1136 {"bookmarkUrl": url,1172 {"bookmarkUrl": url,
1137 "bookmarkTitle": title}) 1173 "bookmarkTitle": title})
1138 }1174 }
1139 }1175 }
11401176
11411177
=== added file 'src/app/webbrowser/DraggableUrlDelegateWide.qml'
--- src/app/webbrowser/DraggableUrlDelegateWide.qml 1970-01-01 00:00:00 +0000
+++ src/app/webbrowser/DraggableUrlDelegateWide.qml 2015-08-12 13:42:27 +0000
@@ -0,0 +1,98 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import Ubuntu.Components 1.3
21
22UrlDelegateWide {
23 id: item
24
25 z: Drag.active ? 1 : 0 // display on top of siblings while dragging
26 Drag.active: gripArea.drag.active
27 Drag.hotSpot.x: grip.x
28 Drag.hotSpot.y: grip.y
29 Drag.onActiveChanged: {
30 if (item.Drag.active) {
31 internal.positionBeforeDrag = Qt.point(x, y)
32 item.dragStarted()
33 }
34 }
35
36 property bool draggable: true
37 property int gripMargin: units.gu(1)
38 signal dragStarted()
39 signal dragEnded(var dragAndDrop)
40
41 // only monitors hover events without capturing any click or drag
42 MouseArea {
43 id: hoverArea
44 anchors.fill: parent
45 acceptedButtons: Qt.NoButton
46 hoverEnabled: true
47 }
48
49 Icon {
50 id: grip
51 objectName: "dragGrip"
52
53 anchors.verticalCenter: parent.verticalCenter
54 anchors.right: parent.right
55 anchors.rightMargin: item.gripMargin
56
57 width: units.gu(3)
58 height: width
59 name: "view-grid-symbolic"
60
61 opacity: item.draggable && hoverArea.containsMouse ? 1.0 : 0.0
62 Behavior on opacity {
63 NumberAnimation {
64 duration: UbuntuAnimation.SnapDuration
65 easing: UbuntuAnimation.StandardEasing
66 }
67 }
68
69 MouseArea {
70 id: gripArea
71 anchors.fill: parent
72 drag.target: item.draggable ? item : null
73 onReleased: {
74 var result = { success: false, target: item.Drag.target }
75 item.dragEnded(result)
76 if (result.success) item.Drag.drop()
77 else {
78 item.x = internal.positionBeforeDrag.x
79 item.y = internal.positionBeforeDrag.y
80 item.Drag.cancel()
81 }
82 }
83 }
84 }
85
86 Rectangle {
87 anchors.fill: parent
88 color: "transparent"
89 border.color: UbuntuColors.lightGrey
90 border.width: 1
91 visible: item.Drag.active
92 }
93
94 QtObject {
95 id: internal
96 property point positionBeforeDrag
97 }
98}
099
=== added file 'src/app/webbrowser/NewTabViewWide.qml'
--- src/app/webbrowser/NewTabViewWide.qml 1970-01-01 00:00:00 +0000
+++ src/app/webbrowser/NewTabViewWide.qml 2015-08-12 13:42:27 +0000
@@ -0,0 +1,317 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import Qt.labs.settings 1.0
21import Ubuntu.Components 1.3
22import webbrowserapp.private 0.1
23import ".."
24
25FocusScope {
26 id: newTabViewWide
27
28 property QtObject bookmarksModel
29 property alias historyModel: historyTimeframeModel.sourceModel
30 property QtObject settingsObject
31 property alias selectedIndex: sections.selectedIndex
32 readonly property bool inBookmarksView: newTabViewWide.selectedIndex === 1
33
34 signal bookmarkClicked(url url)
35 signal bookmarkRemoved(url url)
36 signal historyEntryClicked(url url)
37 signal releasingKeyboardFocus()
38
39 Keys.onTabPressed: selectedIndex = (selectedIndex + 1) % 2
40 Keys.onBacktabPressed: selectedIndex = Math.abs((selectedIndex - 1) % 2)
41 onActiveFocusChanged: {
42 if (activeFocus) {
43 if (inBookmarksView) {
44 if (sections.lastFocusedBookmarksColumn === bookmarksList &&
45 bookmarksList.model.length === 0) {
46 sections.lastFocusedBookmarksColumn = folders
47 }
48 sections.lastFocusedBookmarksColumn.focus = true
49 }
50 else topSitesList.focus = true
51 }
52 }
53
54 LimitProxyModel {
55 id: topSitesModel
56 limit: 10
57 sourceModel: TopSitesModel {
58 sourceModel: HistoryTimeframeModel {
59 id: historyTimeframeModel
60 }
61 }
62 }
63
64 Rectangle {
65 anchors.fill: parent
66 color: "#fbfbfb"
67 }
68
69 ListView {
70 id: folders
71 objectName: "foldersList"
72 visible: inBookmarksView
73
74 Keys.onRightPressed: if (bookmarksList.model.length > 0) bookmarksList.focus = true
75 Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, folders.model.count - 1)
76 Keys.onUpPressed: {
77 if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
78 else newTabViewWide.releasingKeyboardFocus()
79 }
80 onActiveFocusChanged: {
81 if (activeFocus) {
82 sections.lastFocusedBookmarksColumn = folders
83 if (currentIndex < 0) currentIndex = 0
84 }
85 }
86
87 anchors {
88 top: sectionsGroup.bottom
89 bottom: parent.bottom
90 left: parent.left
91 topMargin: units.gu(2)
92 }
93 width: units.gu(25)
94
95 currentIndex: 0
96 model: BookmarksFolderListModel {
97 sourceModel: newTabViewWide.bookmarksModel
98 }
99
100 delegate: ListItem {
101 id: folderItem
102 objectName: "folderItem"
103 property var model: entries
104 property bool isActiveFolder: ListView.isCurrentItem
105 property bool isCurrentItem: ListView.isCurrentItem
106 property bool isAllBookmarksFolder: folder.length === 0
107 property alias name: dropArea.folderName
108 divider.visible: false
109
110 property bool isCurrentDropTarget: dropArea.containsDrag && dropArea.drag.source.folder !== folder
111 color: isCurrentDropTarget ? "green" :
112 ((folders.activeFocus && isActiveFolder) ? Qt.rgba(0, 0, 0, 0.05) : "transparent")
113
114 Label {
115 anchors.verticalCenter: parent.verticalCenter
116 anchors.left: parent.left
117 anchors.right: parent.right
118 anchors.leftMargin: units.gu(2)
119 anchors.rightMargin: units.gu(2)
120
121 fontSize: isAllBookmarksFolder ? "medium" : "small"
122 text: isAllBookmarksFolder ? i18n.tr("All Bookmarks") : folderItem.name
123 color: isActiveFolder ? UbuntuColors.orange : UbuntuColors.darkGrey
124 }
125
126 onClicked: folders.currentIndex = index
127
128 DropArea {
129 id: dropArea
130 anchors.fill: parent
131 property string folderName: folder
132 }
133 }
134 }
135
136 Scrollbar {
137 flickableItem: folders
138 }
139
140 ListView {
141 id: bookmarksList
142 objectName: "bookmarksList"
143 anchors {
144 top: sectionsGroup.bottom
145 bottom: parent.bottom
146 left: folders.right
147 right: parent.right
148 topMargin: units.gu(2)
149 }
150 visible: inBookmarksView
151 onActiveFocusChanged: if (activeFocus) sections.lastFocusedBookmarksColumn = bookmarksList
152
153 // Build a temporary model for the bookmarks list that includes, when
154 // necessary, the homepage bookmark as a fixed first item in the list
155 model: {
156 if (!folders.currentItem) return null
157
158 var items = []
159 if (folders.currentItem.isAllBookmarksFolder) items.push({
160 title: i18n.tr("Homepage"),
161 url: newTabViewWide.settingsObject.homepage,
162 folder: ""
163 })
164
165 if (!folders.currentItem.model) return null
166 for (var i = 0; i < folders.currentItem.model.count; i++) {
167 items.push(folders.currentItem.model.get(i))
168 }
169 return items
170 }
171
172 currentIndex: 0
173
174 delegate: DraggableUrlDelegateWide {
175 objectName: "bookmarkItem"
176 clip: true
177
178 title: modelData.title
179 icon: modelData.icon ? modelData.icon : ""
180 url: modelData.url
181
182 property string folder: modelData.folder
183 property bool isHomeBookmark: folder === "" && index === 0
184
185 removable: !isHomeBookmark
186 draggable: !isHomeBookmark && contentItem.x === 0
187 highlighted: bookmarksList.activeFocus && ListView.isCurrentItem
188
189 onClicked: newTabViewWide.bookmarkClicked(url)
190 onRemoved: newTabViewWide.bookmarkRemoved(url)
191
192 // Larger margin to prevent interference from Scrollbar hovering area
193 gripMargin: units.gu(4)
194 onDragStarted: {
195 // Remove interactivity to prevent the list from scrolling
196 // while dragging near its margins. This ensures we can correctly
197 // return the item to its original position on a failed drop.
198 bookmarksList.interactive = false
199
200 // Relinquish focus as the presses and releases that compose the
201 // drag will move the keyboard focus in a location unexpected
202 // for the user. This way it will go back to the address bar and
203 // the user can predictably resume keyboard interaction from there.
204 newTabViewWide.releasingKeyboardFocus()
205 }
206 onDragEnded: {
207 bookmarksList.interactive = true
208
209 if (dragAndDrop.target && dragAndDrop.target.folderName !== folder) {
210 bookmarksModel.update(modelData.url, modelData.title,
211 dragAndDrop.target.folderName)
212 dragAndDrop.success = true
213 }
214 }
215 }
216
217 Keys.onReturnPressed: newTabViewWide.bookmarkClicked(currentItem.url)
218 Keys.onDeletePressed: {
219 if (currentItem.removable) {
220 newTabViewWide.bookmarkRemoved(currentItem.url)
221 if (bookmarksList.model.length === 0) folders.focus = true
222 }
223 }
224 Keys.onLeftPressed: folders.focus = true
225 Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, model.length - 1)
226 Keys.onUpPressed: {
227 if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
228 else newTabViewWide.releasingKeyboardFocus()
229 }
230 }
231
232 Scrollbar {
233 flickableItem: bookmarksList
234 }
235
236 ListView {
237 id: topSitesList
238 objectName: "topSitesList"
239 anchors {
240 top: sectionsGroup.bottom
241 bottom: parent.bottom
242 left: parent.left
243 right: parent.right
244 topMargin: units.gu(2)
245 }
246
247 visible: !inBookmarksView
248 currentIndex: 0
249
250 model: topSitesModel
251 delegate: UrlDelegateWide {
252 objectName: "topSiteItem"
253 clip: true
254
255 title: model.title
256 icon: model.icon
257 url: model.url
258 highlighted: topSitesList.activeFocus && ListView.isCurrentItem
259
260 onClicked: newTabViewWide.historyEntryClicked(url)
261 onRemoved: newTabViewWide.historyModel.hide(url)
262 }
263
264 Keys.onReturnPressed: newTabViewWide.historyEntryClicked(currentItem.url)
265 Keys.onDeletePressed: {
266 newTabViewWide.historyModel.hide(currentItem.url)
267 if (topSitesList.model.count === 0) newTabViewWide.releasingKeyboardFocus()
268 }
269 Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, model.count - 1)
270 Keys.onUpPressed: {
271 if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
272 else newTabViewWide.releasingKeyboardFocus()
273 }
274 }
275
276 Scrollbar {
277 flickableItem: topSitesList
278 }
279
280 Rectangle {
281 id: sectionsGroup
282 anchors {
283 top: parent.top
284 left: parent.left
285 right: parent.right
286 }
287 color: "#dedede"
288 height: sections.height
289
290 Sections {
291 id: sections
292 objectName: "sections"
293 anchors {
294 left: parent.left
295 top: parent.top
296 leftMargin: units.gu(1)
297 }
298
299 selectedIndex: settingsObject.newTabDefaultSection
300 onSelectedIndexChanged: {
301 settingsObject.newTabDefaultSection = selectedIndex
302 if (selectedIndex === 0) topSitesList.focus = true
303 else {
304 if (lastFocusedBookmarksColumn) lastFocusedBookmarksColumn.focus = true
305 else folders.focus = true
306 }
307
308 }
309 property var lastFocusedBookmarksColumn: folders
310
311 actions: [
312 Action { text: i18n.tr("Top sites") },
313 Action { text: i18n.tr("Bookmarks") }
314 ]
315 }
316 }
317}
0318
=== added file 'src/app/webbrowser/UrlDelegateWide.qml'
--- src/app/webbrowser/UrlDelegateWide.qml 1970-01-01 00:00:00 +0000
+++ src/app/webbrowser/UrlDelegateWide.qml 2015-08-12 13:42:27 +0000
@@ -0,0 +1,86 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import Ubuntu.Components 1.3
21import ".."
22
23ListItem {
24 id: urlDelegate
25
26 property alias icon: icon.source
27 property alias title: title.text
28 property alias url: url.text
29 property bool highlighted: false
30 property bool removable: true
31
32 color: highlighted ? Qt.rgba(0, 0, 0, 0.05) : "transparent"
33
34 divider.visible: false
35 height: units.gu(7)
36
37 signal removed()
38
39 Favicon {
40 id: icon
41 anchors {
42 verticalCenter: parent.verticalCenter
43 left: parent.left
44 leftMargin: units.gu(1.5)
45 }
46 }
47
48 Column {
49 width: parent.width - icon.width - parent.spacing
50 anchors {
51 left: icon.right
52 leftMargin: units.gu(1)
53 verticalCenter: parent.verticalCenter
54 }
55
56 Label {
57 id: title
58
59 fontSize: "small"
60 color: highlighted ? UbuntuColors.orange : UbuntuColors.darkGrey
61 wrapMode: Text.Wrap
62 elide: Text.ElideRight
63 maximumLineCount: 1
64 }
65
66 Label {
67 id: url
68
69 fontSize: "small"
70 color: highlighted ? UbuntuColors.orange : UbuntuColors.darkGrey
71 wrapMode: Text.Wrap
72 elide: Text.ElideRight
73 maximumLineCount: 1
74 }
75 }
76
77 property var _deleteAction: Action {
78 objectName: "leadingAction.delete"
79 iconName: "delete"
80 onTriggered: urlDelegate.removed()
81 }
82
83 leadingActions: ListItemActions {
84 actions: removable ? [_deleteAction] : []
85 }
86}
087
=== modified file 'src/app/webbrowser/bookmarks-folder-model.cpp'
--- src/app/webbrowser/bookmarks-folder-model.cpp 2015-06-17 02:17:45 +0000
+++ src/app/webbrowser/bookmarks-folder-model.cpp 2015-08-12 13:42:27 +0000
@@ -34,7 +34,7 @@
34 with the same name that the filter folder name (case-sensitive34 with the same name that the filter folder name (case-sensitive
35 comparison).35 comparison).
3636
37 When no folder name is set (null or empty string), all entries that 37 When no folder name is set (null or empty string), all entries that
38 are not stored in any folder match.38 are not stored in any folder match.
39*/39*/
40BookmarksFolderModel::BookmarksFolderModel(QObject* parent)40BookmarksFolderModel::BookmarksFolderModel(QObject* parent)
@@ -76,6 +76,26 @@
76 return rowCount();76 return rowCount();
77}77}
7878
79QVariantMap BookmarksFolderModel::get(int row) const
80{
81 if (row < 0 || row >= rowCount()) {
82 return QVariantMap();
83 }
84
85 QVariantMap res;
86 QHash<int,QByteArray> names = roleNames();
87 QHashIterator<int, QByteArray> i(names);
88
89 while (i.hasNext()) {
90 i.next();
91 QModelIndex idx = index(row, 0);
92 QVariant data = idx.data(i.key());
93 res[i.value()] = data;
94 }
95
96 return res;
97}
98
79bool BookmarksFolderModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const99bool BookmarksFolderModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
80{100{
81 QModelIndex index = sourceModel()->index(source_row, 0, source_parent);101 QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
82102
=== modified file 'src/app/webbrowser/bookmarks-folder-model.h'
--- src/app/webbrowser/bookmarks-folder-model.h 2015-06-17 02:17:45 +0000
+++ src/app/webbrowser/bookmarks-folder-model.h 2015-08-12 13:42:27 +0000
@@ -43,6 +43,7 @@
43 void setFolder(const QString& domain);43 void setFolder(const QString& domain);
4444
45 int count() const;45 int count() const;
46 Q_INVOKABLE QVariantMap get(int row) const;
4647
47Q_SIGNALS:48Q_SIGNALS:
48 void sourceModelChanged() const;49 void sourceModelChanged() const;
4950
=== modified file 'src/app/webbrowser/bookmarks-folderlist-model.cpp'
--- src/app/webbrowser/bookmarks-folderlist-model.cpp 2015-07-01 01:23:07 +0000
+++ src/app/webbrowser/bookmarks-folderlist-model.cpp 2015-08-12 13:42:27 +0000
@@ -99,6 +99,7 @@
99 }99 }
100 endResetModel();100 endResetModel();
101 Q_EMIT sourceModelChanged();101 Q_EMIT sourceModelChanged();
102 Q_EMIT countChanged();
102 }103 }
103}104}
104105
@@ -174,6 +175,8 @@
174 beginInsertRows(QModelIndex(), insertAt, insertAt);175 beginInsertRows(QModelIndex(), insertAt, insertAt);
175 addFolder(folder);176 addFolder(folder);
176 endInsertRows();177 endInsertRows();
178
179 Q_EMIT countChanged();
177 }180 }
178}181}
179182
@@ -183,6 +186,8 @@
183 clearFolders();186 clearFolders();
184 populateModel();187 populateModel();
185 endResetModel();188 endResetModel();
189
190 Q_EMIT countChanged();
186}191}
187192
188void BookmarksFolderListModel::addFolder(const QString& folder)193void BookmarksFolderListModel::addFolder(const QString& folder)
189194
=== modified file 'src/app/webbrowser/bookmarks-folderlist-model.h'
--- src/app/webbrowser/bookmarks-folderlist-model.h 2015-06-30 21:09:20 +0000
+++ src/app/webbrowser/bookmarks-folderlist-model.h 2015-08-12 13:42:27 +0000
@@ -32,6 +32,7 @@
32 Q_OBJECT32 Q_OBJECT
3333
34 Q_PROPERTY(BookmarksModel* sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged)34 Q_PROPERTY(BookmarksModel* sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged)
35 Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
3536
36 Q_ENUMS(Roles)37 Q_ENUMS(Roles)
3738
@@ -58,6 +59,7 @@
5859
59Q_SIGNALS:60Q_SIGNALS:
60 void sourceModelChanged() const;61 void sourceModelChanged() const;
62 void countChanged() const;
6163
62private Q_SLOTS:64private Q_SLOTS:
63 void onFolderAdded(const QString& folder);65 void onFolderAdded(const QString& folder);
6466
=== modified file 'tests/autopilot/webbrowser_app/emulators/browser.py'
--- tests/autopilot/webbrowser_app/emulators/browser.py 2015-08-11 10:37:56 +0000
+++ tests/autopilot/webbrowser_app/emulators/browser.py 2015-08-12 13:42:27 +0000
@@ -130,7 +130,10 @@
130 state="shown")130 state="shown")
131131
132 def get_new_tab_view(self):132 def get_new_tab_view(self):
133 return self.wait_select_single("NewTabView", visible=True)133 if self.wide:
134 return self.wait_select_single("NewTabViewWide", visible=True)
135 else:
136 return self.wait_select_single("NewTabView", visible=True)
134137
135 # Since the NewPrivateTabView does not define any new QML property in its138 # Since the NewPrivateTabView does not define any new QML property in its
136 # extended file, it does not report itself to autopilot with the same name139 # extended file, it does not report itself to autopilot with the same name
@@ -166,9 +169,6 @@
166 except exceptions.StateNotFoundError:169 except exceptions.StateNotFoundError:
167 return None170 return None
168171
169 def get_bookmarks_folder_list_view(self):
170 return self.select_single(BookmarksFolderListView)
171
172 def press_key(self, key):172 def press_key(self, key):
173 self.keyboard.press_and_release(key)173 self.keyboard.press_and_release(key)
174174
@@ -442,6 +442,68 @@
442 def get_notopsites_label(self):442 def get_notopsites_label(self):
443 return self.select_single("Label", objectName="notopsites")443 return self.select_single("Label", objectName="notopsites")
444444
445 def get_top_site_items(self):
446 return self.get_top_sites_list().get_delegates()
447
448 def get_bookmarks_folder_list_view(self):
449 return self.select_single(BookmarksFolderListView)
450
451 def get_bookmarks(self, folder_name):
452 # assumes that the "more" button has been clicked
453 folders = self.get_bookmarks_folder_list_view()
454 folder_delegate = folders.get_folder_delegate(folder_name)
455 return folders.get_urls_from_folder(folder_delegate)
456
457 def get_folder_names(self):
458 folders = self.get_bookmarks_folder_list_view().get_delegates()
459 return [folder.folderName for folder in folders]
460
461
462class NewTabViewWide(uitk.UbuntuUIToolkitCustomProxyObjectBase):
463
464 def go_to_section(self, section_index):
465 sections = self.select_single(uitk.Sections)
466 if not sections.selectedIndex == section_index:
467 sections.click_section_button(section_index)
468
469 def get_bookmarks_list(self):
470 self.go_to_section(1)
471 list = self.select_single(uitk.QQuickListView,
472 objectName="bookmarksList")
473 return sorted(list.select_many("DraggableUrlDelegateWide",
474 objectName="bookmarkItem"),
475 key=lambda delegate: delegate.globalRect.y)
476
477 def get_top_sites_list(self):
478 self.go_to_section(0)
479 list = self.select_single(uitk.QQuickListView,
480 objectName="topSitesList")
481 return sorted(list.select_many("UrlDelegateWide",
482 objectName="topSiteItem"),
483 key=lambda delegate: delegate.globalRect.y)
484
485 def get_folders_list(self):
486 self.go_to_section(1)
487 list = self.select_single(uitk.QQuickListView,
488 objectName="foldersList")
489 return sorted(list.select_many(objectName="folderItem"),
490 key=lambda delegate: delegate.globalRect.y)
491
492 def get_top_site_items(self):
493 self.go_to_section(0)
494 return self.get_top_sites_list()
495
496 def get_bookmarks(self, folder_name):
497 folders = self.get_folders_list()
498 matches = [folder for folder in folders if folder.name == folder_name]
499 if not len(matches) == 1:
500 return []
501 self.pointing_device.click_object(matches[0])
502 return self.get_bookmarks_list()
503
504 def get_folder_names(self):
505 return [folder.name for folder in self.get_folders_list()]
506
445507
446class UrlsList(uitk.UbuntuUIToolkitCustomProxyObjectBase):508class UrlsList(uitk.UbuntuUIToolkitCustomProxyObjectBase):
447509
@@ -458,6 +520,17 @@
458 pass520 pass
459521
460522
523class UrlDelegateWide(uitk.UCListItem):
524
525 pass
526
527
528class DraggableUrlDelegateWide(UrlDelegateWide):
529
530 def get_grip(self):
531 return self.select_single("Icon", objectName="dragGrip")
532
533
461class BookmarkOptions(uitk.UbuntuUIToolkitCustomProxyObjectBase):534class BookmarkOptions(uitk.UbuntuUIToolkitCustomProxyObjectBase):
462535
463 def get_title_text_field(self):536 def get_title_text_field(self):
464537
=== modified file 'tests/autopilot/webbrowser_app/tests/__init__.py'
--- tests/autopilot/webbrowser_app/tests/__init__.py 2015-07-09 20:26:53 +0000
+++ tests/autopilot/webbrowser_app/tests/__init__.py 2015-08-12 13:42:27 +0000
@@ -143,7 +143,7 @@
143 time.sleep(1)143 time.sleep(1)
144 return tabs_view144 return tabs_view
145145
146 def open_new_tab(self):146 def open_new_tab(self, open_tabs_view=False, expand_view=False):
147 if (self.main_window.incognito):147 if (self.main_window.incognito):
148 count = len(self.main_window.get_incognito_webviews())148 count = len(self.main_window.get_incognito_webviews())
149 else:149 else:
@@ -152,7 +152,8 @@
152 if self.main_window.wide:152 if self.main_window.wide:
153 self.main_window.chrome.get_tabs_bar().click_new_tab_button()153 self.main_window.chrome.get_tabs_bar().click_new_tab_button()
154 else:154 else:
155 # assumes the tabs view is already open155 if open_tabs_view:
156 self.open_tabs_view()
156 tabs_view = self.main_window.get_tabs_view()157 tabs_view = self.main_window.get_tabs_view()
157 toolbar = self.main_window.get_recent_view_toolbar()158 toolbar = self.main_window.get_recent_view_toolbar()
158 toolbar.click_action("newTabButton")159 toolbar.click_action("newTabButton")
@@ -175,6 +176,11 @@
175 self.main_window.address_bar.activeFocus,176 self.main_window.address_bar.activeFocus,
176 Eventually(Equals(True)))177 Eventually(Equals(True)))
177178
179 if not self.main_window.wide and expand_view:
180 more_button = new_tab_view.get_bookmarks_more_button()
181 self.assertThat(more_button.visible, Equals(True))
182 self.pointing_device.click_object(more_button)
183
178 return new_tab_view184 return new_tab_view
179185
180 def open_settings(self):186 def open_settings(self):
181187
=== modified file 'tests/autopilot/webbrowser_app/tests/test_addressbar_bookmark.py'
--- tests/autopilot/webbrowser_app/tests/test_addressbar_bookmark.py 2015-07-03 15:06:08 +0000
+++ tests/autopilot/webbrowser_app/tests/test_addressbar_bookmark.py 2015-08-12 13:42:27 +0000
@@ -32,9 +32,7 @@
32 bookmark_options.wait_until_destroyed()32 bookmark_options.wait_until_destroyed()
33 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))33 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))
3434
35 if not self.main_window.wide:35 self.open_new_tab(open_tabs_view=True)
36 self.open_tabs_view()
37 self.open_new_tab()
38 url = self.base_url + "/test2"36 url = self.base_url + "/test2"
39 self.main_window.go_to_url(url)37 self.main_window.go_to_url(url)
40 self.main_window.wait_until_page_loaded(url)38 self.main_window.wait_until_page_loaded(url)
@@ -57,9 +55,7 @@
57 self.assertThat(chrome.bookmarked, Eventually(Equals(False)))55 self.assertThat(chrome.bookmarked, Eventually(Equals(False)))
5856
59 def test_cannot_bookmark_empty_page(self):57 def test_cannot_bookmark_empty_page(self):
60 if not self.main_window.wide:58 self.open_new_tab(open_tabs_view=True)
61 self.open_tabs_view()
62 self.open_new_tab()
6359
64 if self.main_window.wide:60 if self.main_window.wide:
65 self.main_window.chrome.get_tabs_bar().select_tab(0)61 self.main_window.chrome.get_tabs_bar().select_tab(0)
6662
=== modified file 'tests/autopilot/webbrowser_app/tests/test_bookmark_options.py'
--- tests/autopilot/webbrowser_app/tests/test_bookmark_options.py 2015-07-09 14:01:15 +0000
+++ tests/autopilot/webbrowser_app/tests/test_bookmark_options.py 2015-08-12 13:42:27 +0000
@@ -86,27 +86,24 @@
86 connection.commit()86 connection.commit()
87 connection.close()87 connection.close()
8888
89 def _get_bookmarks_folders_list_view(self):
90 if not self.main_window.wide:
91 self.open_tabs_view()
92 new_tab_view = self.open_new_tab()
93 more_button = new_tab_view.get_bookmarks_more_button()
94 self.assertThat(more_button.visible, Equals(True))
95 self.pointing_device.click_object(more_button)
96 return self.main_window.get_bookmarks_folder_list_view()
97
98 def _get_bookmark_options(self):89 def _get_bookmark_options(self):
99 address_bar = self.main_window.address_bar90 address_bar = self.main_window.address_bar
100 bookmark_toggle = address_bar.get_bookmark_toggle()91 bookmark_toggle = address_bar.get_bookmark_toggle()
101 self.pointing_device.click_object(bookmark_toggle)92 self.pointing_device.click_object(bookmark_toggle)
102 return self.main_window.get_bookmark_options()93 return self.main_window.get_bookmark_options()
10394
95 def _assert_bookmark_count_in_folder(self, tab, folder_name, count):
96 # in wide mode the list of urls in the default folder has the homepage
97 # bookmark in it, but it does not in narrow mode
98 if self.main_window.wide and folder_name == "":
99 count += 1
100
101 urls = tab.get_bookmarks(folder_name)
102 self.assertThat(lambda: len(urls), Eventually(Equals(count)))
103
104 def test_save_bookmarked_url_in_default_folder(self):104 def test_save_bookmarked_url_in_default_folder(self):
105 folders = self._get_bookmarks_folders_list_view()105 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
106 folder_delegate = folders.get_folder_delegate("")106 self._assert_bookmark_count_in_folder(new_tab, "", 4)
107 self.assertThat(lambda: len(folders.get_urls_from_folder(
108 folder_delegate)),
109 Eventually(Equals(4)))
110107
111 url = self.base_url + "/test2"108 url = self.base_url + "/test2"
112 self.main_window.go_to_url(url)109 self.main_window.go_to_url(url)
@@ -121,20 +118,14 @@
121118
122 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))119 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))
123120
124 folders = self._get_bookmarks_folders_list_view()121 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
125 folder_delegate = folders.get_folder_delegate("")122 self._assert_bookmark_count_in_folder(new_tab, "", 5)
126 self.assertThat(lambda: len(folders.get_urls_from_folder(
127 folder_delegate)),
128 Eventually(Equals(5)))
129123
130 def test_save_bookmarked_url_in_existing_folder(self):124 def test_save_bookmarked_url_in_existing_folder(self):
131 folders = self._get_bookmarks_folders_list_view()125 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
132 self.assertThat(lambda: len(folders.get_delegates()),126 self.assertThat(lambda: len(new_tab.get_folder_names()),
133 Eventually(Equals(3)))127 Eventually(Equals(3)))
134 folder_delegate = folders.get_folder_delegate("Actinide")128 self._assert_bookmark_count_in_folder(new_tab, "Actinide", 1)
135 self.assertThat(lambda: len(folders.get_urls_from_folder(
136 folder_delegate)),
137 Eventually(Equals(1)))
138129
139 url = self.base_url + "/test2"130 url = self.base_url + "/test2"
140 self.main_window.go_to_url(url)131 self.main_window.go_to_url(url)
@@ -158,17 +149,14 @@
158149
159 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))150 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))
160151
161 folders = self._get_bookmarks_folders_list_view()152 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
162 self.assertThat(lambda: len(folders.get_delegates()),153 self.assertThat(lambda: len(new_tab.get_folder_names()),
163 Eventually(Equals(3)))154 Eventually(Equals(3)))
164 folder_delegate = folders.get_folder_delegate("Actinide")155 self._assert_bookmark_count_in_folder(new_tab, "Actinide", 2)
165 self.assertThat(lambda: len(folders.get_urls_from_folder(
166 folder_delegate)),
167 Eventually(Equals(2)))
168156
169 def test_save_bookmarked_url_in_new_folder(self):157 def test_save_bookmarked_url_in_new_folder(self):
170 folders = self._get_bookmarks_folders_list_view()158 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
171 self.assertThat(lambda: len(folders.get_delegates()),159 self.assertThat(lambda: len(new_tab.get_folder_names()),
172 Eventually(Equals(3)))160 Eventually(Equals(3)))
173161
174 url = self.base_url + "/test2"162 url = self.base_url + "/test2"
@@ -205,13 +193,10 @@
205193
206 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))194 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))
207195
208 folders = self._get_bookmarks_folders_list_view()196 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
209 self.assertThat(lambda: len(folders.get_delegates()),197 self.assertThat(lambda: len(new_tab.get_folder_names()),
210 Eventually(Equals(4)))198 Eventually(Equals(4)))
211 folder_delegate = folders.get_folder_delegate("NewFolder")199 self._assert_bookmark_count_in_folder(new_tab, "NewFolder", 1)
212 self.assertThat(lambda: len(folders.get_urls_from_folder(
213 folder_delegate)),
214 Eventually(Equals(1)))
215200
216 @testtools.skip("Temporarily skipped until popover going out of view with"201 @testtools.skip("Temporarily skipped until popover going out of view with"
217 " OSK is fixed http://pad.lv/1466222")202 " OSK is fixed http://pad.lv/1466222")
@@ -235,10 +220,11 @@
235220
236 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))221 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))
237222
238 folders = self._get_bookmarks_folders_list_view()223 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
239 folder_delegate = folders.get_folder_delegate("")224 self._assert_bookmark_count_in_folder(new_tab, "", 5)
240 self.assertThat(lambda: len(folders.get_urls_from_folder(225
241 folder_delegate)),226 index = 0
242 Eventually(Equals(5)))227 if self.main_view.wide:
243 delegate = folders.get_urls_from_folder(folder_delegate)[0]228 index += 1
244 self.assertThat(delegate.title, Equals("NewTitle"))229 bookmark = new_tab.get_bookmarks("")[index]
230 self.assertThat(bookmark.title, Equals("NewTitle"))
245231
=== modified file 'tests/autopilot/webbrowser_app/tests/test_findinpage.py'
--- tests/autopilot/webbrowser_app/tests/test_findinpage.py 2015-08-11 11:16:52 +0000
+++ tests/autopilot/webbrowser_app/tests/test_findinpage.py 2015-08-12 13:42:27 +0000
@@ -140,8 +140,7 @@
140 # (that would otherwise prevent a bottom edge swipe gesture)140 # (that would otherwise prevent a bottom edge swipe gesture)
141 webview = self.main_window.get_current_webview()141 webview = self.main_window.get_current_webview()
142 self.pointing_device.click_object(webview)142 self.pointing_device.click_object(webview)
143 self.open_tabs_view()143 self.open_new_tab(open_tabs_view=True)
144 self.open_new_tab()
145 self.assertThat(bar.findInPageMode, Eventually(Equals(False)))144 self.assertThat(bar.findInPageMode, Eventually(Equals(False)))
146145
147 def test_navigation_in_new_tab_exits_findinpage_mode(self):146 def test_navigation_in_new_tab_exits_findinpage_mode(self):
148147
=== modified file 'tests/autopilot/webbrowser_app/tests/test_new_tab_view.py'
--- tests/autopilot/webbrowser_app/tests/test_new_tab_view.py 2015-07-03 15:06:08 +0000
+++ tests/autopilot/webbrowser_app/tests/test_new_tab_view.py 2015-08-12 13:42:27 +0000
@@ -26,20 +26,18 @@
2626
27from webbrowser_app.tests import StartOpenRemotePageTestCaseBase27from webbrowser_app.tests import StartOpenRemotePageTestCaseBase
2828
29from ubuntuuitoolkit import ToolkitException
30
2931
30class TestNewTabViewLifetime(StartOpenRemotePageTestCaseBase):32class TestNewTabViewLifetime(StartOpenRemotePageTestCaseBase):
3133
32 def test_new_tab_view_destroyed_when_browsing(self):34 def test_new_tab_view_destroyed_when_browsing(self):
33 if not self.main_window.wide:35 new_tab_view = self.open_new_tab(open_tabs_view=True)
34 self.open_tabs_view()
35 new_tab_view = self.open_new_tab()
36 self.main_window.go_to_url(self.base_url + "/test2")36 self.main_window.go_to_url(self.base_url + "/test2")
37 new_tab_view.wait_until_destroyed()37 new_tab_view.wait_until_destroyed()
3838
39 def test_new_tab_view_destroyed_when_closing_tab(self):39 def test_new_tab_view_destroyed_when_closing_tab(self):
40 if not self.main_window.wide:40 new_tab_view = self.open_new_tab(open_tabs_view=True)
41 self.open_tabs_view()
42 new_tab_view = self.open_new_tab()
43 if self.main_window.wide:41 if self.main_window.wide:
44 self.main_window.chrome.get_tabs_bar().close_tab(1)42 self.main_window.chrome.get_tabs_bar().close_tab(1)
45 else:43 else:
@@ -51,13 +49,9 @@
5149
52 def test_new_tab_view_is_shared_between_tabs(self):50 def test_new_tab_view_is_shared_between_tabs(self):
53 # Open one new tab51 # Open one new tab
54 if not self.main_window.wide:52 new_tab_view = self.open_new_tab(open_tabs_view=True)
55 self.open_tabs_view()
56 new_tab_view = self.open_new_tab()
57 # Open a second new tab53 # Open a second new tab
58 if not self.main_window.wide:54 new_tab_view_2 = self.open_new_tab(open_tabs_view=True)
59 self.open_tabs_view()
60 new_tab_view_2 = self.open_new_tab()
61 # Verify that they share the same NewTabView instance55 # Verify that they share the same NewTabView instance
62 self.assertThat(new_tab_view_2.id, Equals(new_tab_view.id))56 self.assertThat(new_tab_view_2.id, Equals(new_tab_view.id))
63 # Close the second new tab, and verify that the NewTabView instance57 # Close the second new tab, and verify that the NewTabView instance
@@ -123,13 +117,9 @@
123 self.main_window.go_to_url(self.base_url + "/test2")117 self.main_window.go_to_url(self.base_url + "/test2")
124 new_private_tab_view.wait_until_destroyed()118 new_private_tab_view.wait_until_destroyed()
125 # Open one new private tab119 # Open one new private tab
126 if not self.main_window.wide:120 new_private_tab_view = self.open_new_tab(open_tabs_view=True)
127 self.open_tabs_view()
128 new_private_tab_view = self.open_new_tab()
129 # Open a second new private tab121 # Open a second new private tab
130 if not self.main_window.wide:122 new_private_tab_view_2 = self.open_new_tab(open_tabs_view=True)
131 self.open_tabs_view()
132 new_private_tab_view_2 = self.open_new_tab()
133 # Verify that they share the same NewPrivateTabView instance123 # Verify that they share the same NewPrivateTabView instance
134 self.assertThat(new_private_tab_view_2.id,124 self.assertThat(new_private_tab_view_2.id,
135 Equals(new_private_tab_view.id))125 Equals(new_private_tab_view.id))
@@ -156,16 +146,14 @@
156 new_private_tab_view.wait_until_destroyed()146 new_private_tab_view.wait_until_destroyed()
157147
158148
159class TestNewTabViewContents(StartOpenRemotePageTestCaseBase):149class TestNewTabViewContentsBase(StartOpenRemotePageTestCaseBase):
160150
161 def setUp(self):151 def setUp(self):
162 self.create_temporary_profile()152 self.create_temporary_profile()
163 self.populate_config()153 self.populate_config()
164 self.populate_bookmarks()154 self.populate_bookmarks()
165 super(TestNewTabViewContents, self).setUp()155 super(TestNewTabViewContentsBase, self).setUp()
166 if not self.main_window.wide:156 self.new_tab_view = self.open_new_tab(open_tabs_view=True)
167 self.open_tabs_view()
168 self.new_tab_view = self.open_new_tab()
169157
170 def populate_config(self):158 def populate_config(self):
171 self.homepage = "http://test/test2"159 self.homepage = "http://test/test2"
@@ -226,6 +214,14 @@
226 connection.commit()214 connection.commit()
227 connection.close()215 connection.close()
228216
217
218class TestNewTabViewContentsNarrow(TestNewTabViewContentsBase):
219
220 def setUp(self):
221 super(TestNewTabViewContentsNarrow, self).setUp()
222 if self.main_window.wide:
223 self.skipTest("Only on narrow form factors")
224
229 def test_default_home_bookmark(self):225 def test_default_home_bookmark(self):
230 homepage_bookmark = self.new_tab_view.get_homepage_bookmark()226 homepage_bookmark = self.new_tab_view.get_homepage_bookmark()
231 self.assertThat(homepage_bookmark.url, Equals(self.homepage))227 self.assertThat(homepage_bookmark.url, Equals(self.homepage))
@@ -233,10 +229,18 @@
233 self.new_tab_view.wait_until_destroyed()229 self.new_tab_view.wait_until_destroyed()
234 self.main_window.wait_until_page_loaded(self.homepage)230 self.main_window.wait_until_page_loaded(self.homepage)
235231
236 def test_open_bookmark_when_collapsed(self):232 def test_open_top_site(self):
233 top_sites = self.new_tab_view.get_top_sites_list()
234 self.assertThat(lambda: len(top_sites.get_delegates()),
235 Eventually(Equals(1)))
236 top_site = top_sites.get_delegates()[0]
237 url = top_site.url
238 self.pointing_device.click_object(top_site)
239 self.new_tab_view.wait_until_destroyed()
240 self.main_window.wait_until_page_loaded(url)
241
242 def test_open_bookmark(self):
237 bookmarks = self.new_tab_view.get_bookmarks_list()243 bookmarks = self.new_tab_view.get_bookmarks_list()
238 self.assertThat(lambda: len(bookmarks.get_delegates()),
239 Eventually(Equals(4)))
240 bookmark = bookmarks.get_delegates()[1]244 bookmark = bookmarks.get_delegates()[1]
241 url = bookmark.url245 url = bookmark.url
242 self.pointing_device.click_object(bookmark)246 self.pointing_device.click_object(bookmark)
@@ -247,7 +251,7 @@
247 more_button = self.new_tab_view.get_bookmarks_more_button()251 more_button = self.new_tab_view.get_bookmarks_more_button()
248 self.assertThat(more_button.visible, Equals(True))252 self.assertThat(more_button.visible, Equals(True))
249 self.pointing_device.click_object(more_button)253 self.pointing_device.click_object(more_button)
250 folders = self.main_window.get_bookmarks_folder_list_view()254 folders = self.new_tab_view.get_bookmarks_folder_list_view()
251 folder_delegate = folders.get_folder_delegate("")255 folder_delegate = folders.get_folder_delegate("")
252 self.assertThat(lambda: len(folders.get_urls_from_folder(256 self.assertThat(lambda: len(folders.get_urls_from_folder(
253 folder_delegate)),257 folder_delegate)),
@@ -269,7 +273,7 @@
269 more_button = self.new_tab_view.get_bookmarks_more_button()273 more_button = self.new_tab_view.get_bookmarks_more_button()
270 self.assertThat(more_button.visible, Equals(True))274 self.assertThat(more_button.visible, Equals(True))
271 self.pointing_device.click_object(more_button)275 self.pointing_device.click_object(more_button)
272 folders = self.main_window.get_bookmarks_folder_list_view()276 folders = self.new_tab_view.get_bookmarks_folder_list_view()
273 folder_delegate = folders.get_folder_delegate("")277 folder_delegate = folders.get_folder_delegate("")
274 self.assertThat(lambda: len(folders.get_urls_from_folder(278 self.assertThat(lambda: len(folders.get_urls_from_folder(
275 folder_delegate)),279 folder_delegate)),
@@ -292,7 +296,7 @@
292 Eventually(NotEquals(url)))296 Eventually(NotEquals(url)))
293297
294 def _remove_first_bookmark_from_folder(self, folder):298 def _remove_first_bookmark_from_folder(self, folder):
295 folders = self.main_window.get_bookmarks_folder_list_view()299 folders = self.new_tab_view.get_bookmarks_folder_list_view()
296 folder_delegate = folders.get_folder_delegate(folder)300 folder_delegate = folders.get_folder_delegate(folder)
297 delegate = folders.get_urls_from_folder(folder_delegate)[0]301 delegate = folders.get_urls_from_folder(folder_delegate)[0]
298 url = delegate.url302 url = delegate.url
@@ -319,7 +323,7 @@
319 more_button = self.new_tab_view.get_bookmarks_more_button()323 more_button = self.new_tab_view.get_bookmarks_more_button()
320 self.assertThat(more_button.visible, Equals(True))324 self.assertThat(more_button.visible, Equals(True))
321 self.pointing_device.click_object(more_button)325 self.pointing_device.click_object(more_button)
322 folders = self.main_window.get_bookmarks_folder_list_view()326 folders = self.new_tab_view.get_bookmarks_folder_list_view()
323 folder_delegate = folders.get_folder_delegate("")327 folder_delegate = folders.get_folder_delegate("")
324 self.assertThat(lambda: len(folders.get_urls_from_folder(328 self.assertThat(lambda: len(folders.get_urls_from_folder(
325 folder_delegate)),329 folder_delegate)),
@@ -335,7 +339,7 @@
335 more_button = self.new_tab_view.get_bookmarks_more_button()339 more_button = self.new_tab_view.get_bookmarks_more_button()
336 self.assertThat(more_button.visible, Equals(True))340 self.assertThat(more_button.visible, Equals(True))
337 self.pointing_device.click_object(more_button)341 self.pointing_device.click_object(more_button)
338 folders = self.main_window.get_bookmarks_folder_list_view()342 folders = self.new_tab_view.get_bookmarks_folder_list_view()
339 self.assertThat(lambda: len(folders.get_delegates()),343 self.assertThat(lambda: len(folders.get_delegates()),
340 Eventually(Equals(3)))344 Eventually(Equals(3)))
341 folder_delegate = folders.get_folder_delegate("")345 folder_delegate = folders.get_folder_delegate("")
@@ -355,7 +359,7 @@
355 more_button = self.new_tab_view.get_bookmarks_more_button()359 more_button = self.new_tab_view.get_bookmarks_more_button()
356 self.assertThat(more_button.visible, Equals(True))360 self.assertThat(more_button.visible, Equals(True))
357 self.pointing_device.click_object(more_button)361 self.pointing_device.click_object(more_button)
358 folders = self.main_window.get_bookmarks_folder_list_view()362 folders = self.new_tab_view.get_bookmarks_folder_list_view()
359 self.assertThat(lambda: len(folders.get_delegates()),363 self.assertThat(lambda: len(folders.get_delegates()),
360 Eventually(Equals(3)))364 Eventually(Equals(3)))
361 folder_delegate = folders.get_folder_delegate("Actinide")365 folder_delegate = folders.get_folder_delegate("Actinide")
@@ -378,7 +382,7 @@
378 more_button = self.new_tab_view.get_bookmarks_more_button()382 more_button = self.new_tab_view.get_bookmarks_more_button()
379 self.assertThat(more_button.visible, Equals(True))383 self.assertThat(more_button.visible, Equals(True))
380 self.pointing_device.click_object(more_button)384 self.pointing_device.click_object(more_button)
381 folders = self.main_window.get_bookmarks_folder_list_view()385 folders = self.new_tab_view.get_bookmarks_folder_list_view()
382 self.assertThat(lambda: len(folders.get_delegates()),386 self.assertThat(lambda: len(folders.get_delegates()),
383 Eventually(Equals(3)))387 Eventually(Equals(3)))
384 folder_delegate = folders.get_folder_delegate("")388 folder_delegate = folders.get_folder_delegate("")
@@ -396,16 +400,6 @@
396 folder_delegate)),400 folder_delegate)),
397 Eventually(Equals(4)))401 Eventually(Equals(4)))
398402
399 def test_open_top_site(self):
400 top_sites = self.new_tab_view.get_top_sites_list()
401 self.assertThat(lambda: len(top_sites.get_delegates()),
402 Eventually(Equals(1)))
403 top_site = top_sites.get_delegates()[0]
404 url = top_site.url
405 self.pointing_device.click_object(top_site)
406 self.new_tab_view.wait_until_destroyed()
407 self.main_window.wait_until_page_loaded(url)
408
409 def test_remove_top_sites(self):403 def test_remove_top_sites(self):
410 top_sites = self.new_tab_view.get_top_sites_list()404 top_sites = self.new_tab_view.get_top_sites_list()
411 self.assertThat(lambda: len(top_sites.get_delegates()),405 self.assertThat(lambda: len(top_sites.get_delegates()),
@@ -418,3 +412,87 @@
418 self.assertThat(lambda: len(top_sites.get_delegates()),412 self.assertThat(lambda: len(top_sites.get_delegates()),
419 Eventually(Equals(0)))413 Eventually(Equals(0)))
420 self.assertThat(notopsites_label.visible, Eventually(Equals(True)))414 self.assertThat(notopsites_label.visible, Eventually(Equals(True)))
415
416
417class TestNewTabViewContentsWide(TestNewTabViewContentsBase):
418
419 def setUp(self):
420 super(TestNewTabViewContentsWide, self).setUp()
421 if not self.main_window.wide:
422 self.skipTest("Only on wide form factors")
423
424 def test_remove_bookmarks(self):
425 view = self.new_tab_view
426 bookmarks = view.get_bookmarks_list()
427 previous_count = len(bookmarks)
428 bookmarks[1].trigger_leading_action("leadingAction.delete",
429 bookmarks[1].wait_until_destroyed)
430 bookmarks = view.get_bookmarks_list()
431 self.assertThat(len(bookmarks), Equals(previous_count - 1))
432 previous_count = len(bookmarks)
433
434 # verify that trying to delete the homepage bookmark is not going to
435 # do anything because there is no delete action on the delegate
436 no_delete_action = False
437 try:
438 bookmarks[0].trigger_leading_action("leadingAction.delete")
439 except ToolkitException:
440 no_delete_action = True
441 self.assertThat(no_delete_action, Equals(True))
442 self.assertThat(len(view.get_bookmarks_list()), Equals(previous_count))
443
444 def test_remove_top_sites(self):
445 view = self.new_tab_view
446 topsites = view.get_top_sites_list()
447 previous_count = len(topsites)
448 topsites[0].trigger_leading_action("leadingAction.delete",
449 topsites[0].wait_until_destroyed)
450 self.assertThat(len(view.get_top_sites_list()),
451 Equals(previous_count - 1))
452
453 def test_drag_bookmarks(self):
454 view = self.new_tab_view
455 folders = view.get_folders_list()
456 bookmarks = view.get_bookmarks_list()
457 previous_count = len(bookmarks)
458 bookmark = bookmarks[1]
459 title = bookmark.title
460 grip = bookmark.get_grip()
461 original_x = grip.globalRect.x
462 original_y = grip.globalRect.y
463
464 # Test that when hovering normal bookmarks item the grip appears
465 self.assertThat(grip.opacity, Equals(0))
466 self.pointing_device.move_to_object(bookmark)
467 self.assertThat(grip.opacity, Eventually(Equals(1.0)))
468
469 # Test that an item bounces back when dragged within the list itself
470 self.pointing_device.drag(original_x, original_y,
471 original_x, original_y + 200)
472
473 # Test that an item bounces back when dragged to the same folder
474 folder = folders[0]
475 folder_cx = folder.globalRect.x + folder.width / 2
476 folder_cy = folder.globalRect.y + folder.height / 2
477 self.pointing_device.drag(original_x, original_y,
478 folder_cx, folder_cy)
479
480 self.assertThat(lambda: (grip.globalRect.x, grip.globalRect.y),
481 Eventually(Equals((original_x, original_y))))
482
483 # Test that dragging an item to another folder removes it from this one
484 # and adds it to the target folder
485 folder = folders[2]
486 folder_cx = folder.globalRect.x + folder.width / 2
487 folder_cy = folder.globalRect.y + folder.height / 2
488 self.pointing_device.drag(original_x, original_y,
489 folder_cx, folder_cy)
490
491 self.assertThat(lambda: len(view.get_bookmarks_list()),
492 Eventually(NotEquals(previous_count)))
493
494 # Verify that the item has been added to the top of the target folder
495 self.pointing_device.click_object(folder)
496 self.assertThat(lambda: len(view.get_bookmarks_list()),
497 Eventually(Equals(2)))
498 self.assertThat(view.get_bookmarks_list()[0].title, Equals(title))
421499
=== modified file 'tests/autopilot/webbrowser_app/tests/test_private.py'
--- tests/autopilot/webbrowser_app/tests/test_private.py 2015-07-02 13:51:07 +0000
+++ tests/autopilot/webbrowser_app/tests/test_private.py 2015-08-12 13:42:27 +0000
@@ -22,12 +22,6 @@
2222
23class TestPrivateView(StartOpenRemotePageTestCaseBase):23class TestPrivateView(StartOpenRemotePageTestCaseBase):
2424
25 def get_url_list_from_top_sites(self):
26 if not self.main_window.wide:
27 self.open_tabs_view()
28 new_tab_view = self.open_new_tab()
29 return new_tab_view.get_top_sites_list().get_urls()
30
31 def test_going_in_and_out_private_mode(self):25 def test_going_in_and_out_private_mode(self):
32 address_bar = self.main_window.address_bar26 address_bar = self.main_window.address_bar
33 address_bar.focus()27 address_bar.focus()
@@ -72,8 +66,9 @@
72 self.assertTrue(self.main_window.is_new_private_tab_view_visible())66 self.assertTrue(self.main_window.is_new_private_tab_view_visible())
7367
74 def test_url_showing_in_top_sites_in_and_out_private_mode(self):68 def test_url_showing_in_top_sites_in_and_out_private_mode(self):
75 top_sites = self.get_url_list_from_top_sites()69 new_tab = self.open_new_tab(open_tabs_view=True)
76 self.assertIn(self.url, top_sites)70 urls = [site.url for site in new_tab.get_top_site_items()]
71 self.assertIn(self.url, urls)
7772
78 self.main_window.enter_private_mode()73 self.main_window.enter_private_mode()
79 self.assertThat(self.main_window.is_in_private_mode,74 self.assertThat(self.main_window.is_in_private_mode,
@@ -84,13 +79,13 @@
84 self.main_window.leave_private_mode()79 self.main_window.leave_private_mode()
85 self.assertThat(self.main_window.is_in_private_mode,80 self.assertThat(self.main_window.is_in_private_mode,
86 Eventually(Equals(False)))81 Eventually(Equals(False)))
87 top_sites = self.get_url_list_from_top_sites()82
88 self.assertNotIn(url, top_sites)83 new_tab = self.open_new_tab(open_tabs_view=True)
84 urls = [site.url for site in new_tab.get_top_site_items()]
85 self.assertNotIn(url, urls)
8986
90 def test_public_tabs_should_not_be_visible_in_private_mode(self):87 def test_public_tabs_should_not_be_visible_in_private_mode(self):
91 if not self.main_window.wide:88 self.open_new_tab(open_tabs_view=True)
92 self.open_tabs_view()
93 self.open_new_tab()
94 new_tab_view = self.main_window.get_new_tab_view()89 new_tab_view = self.main_window.get_new_tab_view()
95 url = self.base_url + "/test2"90 url = self.base_url + "/test2"
96 self.main_window.go_to_url(url)91 self.main_window.go_to_url(url)
9792
=== modified file 'tests/autopilot/webbrowser_app/tests/test_tabs.py'
--- tests/autopilot/webbrowser_app/tests/test_tabs.py 2015-07-02 13:51:07 +0000
+++ tests/autopilot/webbrowser_app/tests/test_tabs.py 2015-08-12 13:42:27 +0000
@@ -161,9 +161,7 @@
161 webview.activeFocus.wait_for(True)161 webview.activeFocus.wait_for(True)
162162
163 def test_webview_requests_close(self):163 def test_webview_requests_close(self):
164 if not self.main_window.wide:164 self.open_new_tab(open_tabs_view=True)
165 self.open_tabs_view()
166 self.open_new_tab()
167 url = self.base_url + "/closeself"165 url = self.base_url + "/closeself"
168 self.main_window.go_to_url(url)166 self.main_window.go_to_url(url)
169 self.main_window.wait_until_page_loaded(url)167 self.main_window.wait_until_page_loaded(url)
@@ -174,9 +172,7 @@
174 self.assert_number_webviews_eventually(1)172 self.assert_number_webviews_eventually(1)
175173
176 def test_last_webview_requests_close(self):174 def test_last_webview_requests_close(self):
177 if not self.main_window.wide:175 self.open_new_tab(open_tabs_view=True)
178 self.open_tabs_view()
179 self.open_new_tab()
180 url = self.base_url + "/closeself"176 url = self.base_url + "/closeself"
181 self.main_window.go_to_url(url)177 self.main_window.go_to_url(url)
182 self.main_window.wait_until_page_loaded(url)178 self.main_window.wait_until_page_loaded(url)
183179
=== modified file 'tests/unittests/bookmarks-folder-model/tst_BookmarksFolderModelTests.cpp'
--- tests/unittests/bookmarks-folder-model/tst_BookmarksFolderModelTests.cpp 2015-07-02 13:16:56 +0000
+++ tests/unittests/bookmarks-folder-model/tst_BookmarksFolderModelTests.cpp 2015-08-12 13:42:27 +0000
@@ -88,18 +88,21 @@
8888
89 void shouldFilterOutNonMatchingFolders()89 void shouldFilterOutNonMatchingFolders()
90 {90 {
91 bookmarks->add(QUrl("http://example.org/"), "Example Domain", QUrl(), "");91 bookmarks->add(QUrl("http://example.org/"), "Example Domain Org", QUrl(), "");
92 bookmarks->add(QUrl("http://example.com/"), "Example Domain", QUrl(), "SampleFolder01");92 bookmarks->add(QUrl("http://example.com/"), "Example Domain Com", QUrl(), "SampleFolder01");
93 bookmarks->add(QUrl("http://example.net/"), "Example Domain", QUrl(), "SampleFolder02");93 bookmarks->add(QUrl("http://example.net/"), "Example Domain Net", QUrl("http://example.net/icon.png"), "SampleFolder02");
94 model->setFolder("");94 model->setFolder("");
95 QCOMPARE(model->rowCount(), 1);95 QCOMPARE(model->rowCount(), 1);
96 QCOMPARE(model->data(model->index(0, 0), BookmarksModel::Url).toUrl(), QUrl("http://example.org/"));96 QCOMPARE(model->data(model->index(0, 0), BookmarksModel::Url).toUrl(), QUrl("http://example.org/"));
97 QCOMPARE(model->get(0).value("url").toUrl(), QUrl("http://example.org/"));
97 model->setFolder("SampleFolder01");98 model->setFolder("SampleFolder01");
98 QCOMPARE(model->rowCount(), 1);99 QCOMPARE(model->rowCount(), 1);
99 QCOMPARE(model->data(model->index(0, 0), BookmarksModel::Url).toUrl(), QUrl("http://example.com/"));100 QCOMPARE(model->data(model->index(0, 0), BookmarksModel::Url).toUrl(), QUrl("http://example.com/"));
101 QCOMPARE(model->get(0).value("title").toString(), QString("Example Domain Com"));
100 model->setFolder("SampleFolder02");102 model->setFolder("SampleFolder02");
101 QCOMPARE(model->rowCount(), 1);103 QCOMPARE(model->rowCount(), 1);
102 QCOMPARE(model->data(model->index(0, 0), BookmarksModel::Url).toUrl(), QUrl("http://example.net/"));104 QCOMPARE(model->data(model->index(0, 0), BookmarksModel::Url).toUrl(), QUrl("http://example.net/"));
105 QCOMPARE(model->get(0).value("icon").toUrl(), QUrl("http://example.net/icon.png"));
103 model->setFolder("AnotherFolder");106 model->setFolder("AnotherFolder");
104 QCOMPARE(model->rowCount(), 0);107 QCOMPARE(model->rowCount(), 0);
105 }108 }
106109
=== modified file 'tests/unittests/qml/CMakeLists.txt'
--- tests/unittests/qml/CMakeLists.txt 2015-07-09 20:27:00 +0000
+++ tests/unittests/qml/CMakeLists.txt 2015-08-12 13:42:27 +0000
@@ -4,6 +4,7 @@
4find_package(Qt5Qml REQUIRED)4find_package(Qt5Qml REQUIRED)
5find_package(Qt5Quick REQUIRED)5find_package(Qt5Quick REQUIRED)
6find_package(Qt5QuickTest REQUIRED)6find_package(Qt5QuickTest REQUIRED)
7find_package(Qt5Sql REQUIRED)
78
8set(XVFB_COMMAND)9set(XVFB_COMMAND)
9find_program(XVFBRUN xvfb-run)10find_program(XVFBRUN xvfb-run)
@@ -16,9 +17,16 @@
16set(TEST tst_QmlTests)17set(TEST tst_QmlTests)
17set(SOURCES18set(SOURCES
18 ${webbrowser-common_SOURCE_DIR}/favicon-fetcher.cpp19 ${webbrowser-common_SOURCE_DIR}/favicon-fetcher.cpp
20 ${webbrowser-app_SOURCE_DIR}/bookmarks-model.cpp
21 ${webbrowser-app_SOURCE_DIR}/bookmarks-folder-model.cpp
22 ${webbrowser-app_SOURCE_DIR}/bookmarks-folderlist-model.cpp
19 ${webbrowser-app_SOURCE_DIR}/file-operations.cpp23 ${webbrowser-app_SOURCE_DIR}/file-operations.cpp
24 ${webbrowser-app_SOURCE_DIR}/history-model.cpp
25 ${webbrowser-app_SOURCE_DIR}/history-timeframe-model.cpp
26 ${webbrowser-app_SOURCE_DIR}/limit-proxy-model.cpp
20 ${webbrowser-app_SOURCE_DIR}/searchengine.cpp27 ${webbrowser-app_SOURCE_DIR}/searchengine.cpp
21 ${webbrowser-app_SOURCE_DIR}/tabs-model.cpp28 ${webbrowser-app_SOURCE_DIR}/tabs-model.cpp
29 ${webbrowser-app_SOURCE_DIR}/top-sites-model.cpp
22 tst_QmlTests.cpp30 tst_QmlTests.cpp
23)31)
24add_executable(${TEST} ${SOURCES})32add_executable(${TEST} ${SOURCES})
@@ -33,6 +41,7 @@
33 Qt5::Qml41 Qt5::Qml
34 Qt5::Quick42 Qt5::Quick
35 Qt5::QuickTest43 Qt5::QuickTest
44 Qt5::Sql
36)45)
37add_test(${TEST} ${XVFB_COMMAND} ${CMAKE_CURRENT_BINARY_DIR}/${TEST}46add_test(${TEST} ${XVFB_COMMAND} ${CMAKE_CURRENT_BINARY_DIR}/${TEST}
38 -input ${CMAKE_CURRENT_SOURCE_DIR}47 -input ${CMAKE_CURRENT_SOURCE_DIR}
3948
=== added file 'tests/unittests/qml/tst_NewTabViewWide.qml'
--- tests/unittests/qml/tst_NewTabViewWide.qml 1970-01-01 00:00:00 +0000
+++ tests/unittests/qml/tst_NewTabViewWide.qml 2015-08-12 13:42:27 +0000
@@ -0,0 +1,372 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import QtTest 1.0
21import Ubuntu.Test 1.0
22import "../../../src/app/webbrowser"
23import webbrowserapp.private 0.1
24
25Item {
26 id: root
27
28 width: 800
29 height: 600
30
31 Component {
32 id: historyModel
33 HistoryModel {
34 databasePath: ":memory:"
35 }
36 }
37
38 Component {
39 id: bookmarksModel
40 BookmarksModel {
41 databasePath: ":memory:"
42 }
43 }
44
45 property NewTabViewWide view
46 property var bookmarks
47 property var history
48 property string homepage: "http://example.com/homepage"
49
50 Component {
51 id: viewComponent
52 NewTabViewWide {
53 anchors.fill: parent
54 settingsObject: QtObject {
55 property url homepage: root.homepage
56 property int newTabDefaultSection: 0
57 }
58 bookmarksModel: bookmarks
59 historyModel: history
60 }
61 }
62
63 SignalSpy {
64 id: releasingKeyboardFocusSpy
65 signalName: "releasingKeyboardFocus"
66 }
67
68 SignalSpy {
69 id: historyEntryClickedSpy
70 signalName: "historyEntryClicked"
71 }
72
73 SignalSpy {
74 id: bookmarkClickedSpy
75 signalName: "bookmarkClicked"
76 }
77
78 SignalSpy {
79 id: bookmarkRemovedSpy
80 signalName: "bookmarkRemoved"
81 }
82
83 UbuntuTestCase {
84 name: "NewTabViewWide"
85 when: windowShown
86
87 function init() {
88 bookmarks = bookmarksModel.createObject()
89 history = historyModel.createObject()
90 view = viewComponent.createObject(root)
91 populate()
92
93 view.focus = true
94
95 releasingKeyboardFocusSpy.target = view
96 releasingKeyboardFocusSpy.clear()
97 historyEntryClickedSpy.target = view
98 historyEntryClickedSpy.clear()
99 bookmarkClickedSpy.target = view
100 bookmarkClickedSpy.clear()
101 bookmarkRemovedSpy.target = view
102 bookmarkRemovedSpy.clear()
103 }
104
105 function populate() {
106 history.add("http://example.com", "Example Com", "")
107 history.add("http://example.org", "Example Org", "")
108 history.add("http://example.net", "Example Net", "")
109 bookmarks.add("http://example.com", "Example Com", "", "")
110 bookmarks.add("http://example.org/bar", "Example Org Bar", "", "Folder B")
111 bookmarks.add("http://example.org/foo", "Example Org Foo", "", "Folder B")
112 bookmarks.add("http://example.net/a", "Example Net A", "", "Folder A")
113 bookmarks.add("http://example.net/b", "Example Net B", "", "Folder A")
114 }
115
116 function cleanup() {
117 history.destroy()
118 history = null
119 bookmarks.destroy()
120 bookmarks = null
121
122 view.destroy()
123 view = null
124 }
125
126 function clickItem(item) {
127 var center = centerOf(item)
128 mouseClick(item, center.x, center.y)
129 }
130
131 function getListItems(name, itemName) {
132 var list = findChild(view, name)
133 var items = []
134 if (list) {
135 // ensure all the delegates are created
136 list.cacheBuffer = list.count * 1000
137
138 // In some cases the ListView might add other children to the
139 // contentItem, so we filter the list of children to include
140 // only actual delegates
141 var children = list.contentItem.children
142 for (var i = 0; i < children.length; i++) {
143 if (children[i].objectName === itemName) {
144 items.push(children[i])
145 }
146 }
147 }
148 return items
149 }
150
151 function goToBookmarks() {
152 findChild(view, "sections").selectedIndex = 1
153 }
154
155 function test_topsites_list() {
156 // add 8 more top sites so that we are beyond the limit of 10
157 for (var i = 0; i < 8; i++) {
158 history.add("http://example.com/" + i, "Example Com " + i, "")
159 }
160
161 var items = getListItems("topSitesList", "topSiteItem")
162 compare(items.length, 10)
163 compare(items[0].title, "Example Com")
164 compare(items[1].title, "Example Org")
165 compare(items[2].title, "Example Net")
166 for (var i = 0; i < 7; i++) {
167 compare(items[i + 3].title, "Example Com " + i)
168 }
169 }
170
171 function test_folder_list() {
172 var items = getListItems("foldersList", "folderItem")
173 compare(items.length, 3)
174 verify(items[0].isAllBookmarksFolder)
175 compare(items[0].model.folder, "")
176 // named folder items should appear alphabetically sorted
177 compare(items[1].model.folder, "Folder A")
178 compare(items[2].model.folder, "Folder B")
179 }
180
181 function test_all_bookmarks_list() {
182 var items = getListItems("bookmarksList", "bookmarkItem")
183 compare(items.length, 2)
184 compare(items[0].url, homepage)
185 compare(items[1].title, "Example Com")
186 }
187
188 function test_switch_sections_by_keyboard() {
189 skip("Would fail due to UITK bug: http://pad.lv/1481233")
190 var sections = findChild(view, "sections")
191 var folders = findChild(view, "foldersList")
192 var bookmarks = findChild(view, "bookmarksList")
193 var topSites = findChild(view, "topSitesList")
194 compare(sections.selectedIndex, 0)
195 verify(topSites.visible)
196 verify(!folders.visible)
197 verify(!bookmarks.visible)
198
199 keyClick(Qt.Key_Tab)
200 compare(sections.selectedIndex, 1)
201 verify(!topSites.visible)
202 verify(folders.visible)
203 verify(bookmarks.visible)
204
205 keyClick(Qt.Key_Backtab)
206 compare(sections.selectedIndex, 0)
207 }
208
209 function test_navigate_topsites_by_keyboard() {
210 var items = getListItems("topSitesList", "topSiteItem")
211 findChild(view, "topSitesList").currentIndex = 0
212 verify(items[0].highlighted)
213 keyClick(Qt.Key_Down)
214 verify(!items[0].highlighted)
215 verify(items[1].highlighted)
216 keyClick(Qt.Key_Down)
217 verify(items[2].highlighted)
218 keyClick(Qt.Key_Down) // ensure no scrolling past bottom boundary
219 verify(items[2].highlighted)
220 keyClick(Qt.Key_Up)
221 verify(items[1].highlighted)
222 keyClick(Qt.Key_Up)
223 verify(items[0].highlighted)
224 keyClick(Qt.Key_Up)
225 verify(items[0].highlighted)
226 compare(releasingKeyboardFocusSpy.count, 1)
227 }
228
229 function test_activate_topsites_by_keyboard() {
230 var items = getListItems("topSitesList", "topSiteItem")
231 keyClick(Qt.Key_Return)
232 compare(historyEntryClickedSpy.count, 1)
233 compare(historyEntryClickedSpy.signalArguments[0][0], "http://example.com")
234 keyClick(Qt.Key_Down)
235 keyClick(Qt.Key_Return)
236 compare(historyEntryClickedSpy.count, 2)
237 compare(historyEntryClickedSpy.signalArguments[1][0], "http://example.org")
238 }
239
240 function test_navigate_folders_by_keyboard() {
241 goToBookmarks()
242
243 var foldersList = getListItems(view, "foldersList")
244 var folders = getListItems("foldersList", "folderItem")
245 verify(folders[0].isActiveFolder)
246
247 keyClick(Qt.Key_Down)
248 verify(!folders[0].isActiveFolder)
249 verify(folders[1].isActiveFolder)
250
251 // bookmarks within a folder are sorted with the first bookmarked appearing last
252 var items = getListItems("bookmarksList", "bookmarkItem")
253 compare(items[0].title, "Example Net B")
254 compare(items[1].title, "Example Net A")
255 compare(items.length, 2)
256
257 keyClick(Qt.Key_Down)
258 verify(folders[2].isActiveFolder)
259 items = getListItems("bookmarksList", "bookmarkItem")
260 compare(items[0].title, "Example Org Foo")
261 compare(items[1].title, "Example Org Bar")
262 compare(items.length, 2)
263
264 // verify scrolling beyond bottom of list is not allowed
265 keyClick(Qt.Key_Down)
266 verify(folders[2].isActiveFolder)
267
268 keyClick(Qt.Key_Up)
269 verify(folders[1].isActiveFolder)
270 keyClick(Qt.Key_Up)
271 verify(folders[0].isActiveFolder)
272
273 keyClick(Qt.Key_Up)
274 compare(releasingKeyboardFocusSpy.count, 1)
275 }
276
277 function test_switch_between_folder_and_bookmarks_by_keyboard() {
278 goToBookmarks()
279
280 var folders = findChild(view, "foldersList")
281 var bookmarks = findChild(view, "bookmarksList")
282
283 keyClick(Qt.Key_Right)
284 verify(bookmarks.activeFocus)
285 keyClick(Qt.Key_Right)
286 verify(bookmarks.activeFocus) // verify no circular scrolling
287
288 keyClick(Qt.Key_Left)
289 verify(folders.activeFocus)
290 keyClick(Qt.Key_Left)
291 verify(folders.activeFocus) // verify no circular scrolling
292 }
293
294 function test_activate_bookmarks_by_keyboard() {
295 goToBookmarks()
296 keyClick(Qt.Key_Right)
297
298 var items = getListItems("bookmarksList", "bookmarkItem")
299 keyClick(Qt.Key_Return)
300 compare(bookmarkClickedSpy.count, 1)
301 compare(bookmarkClickedSpy.signalArguments[0][0], homepage)
302
303 keyClick(Qt.Key_Down)
304 keyClick(Qt.Key_Return)
305 compare(bookmarkClickedSpy.count, 2)
306 compare(bookmarkClickedSpy.signalArguments[1][0], "http://example.com")
307 }
308
309 function test_activate_topsites_by_mouse() {
310 var items = getListItems("topSitesList", "topSiteItem")
311 clickItem(items[0])
312 compare(historyEntryClickedSpy.count, 1)
313 compare(historyEntryClickedSpy.signalArguments[0][0], "http://example.com")
314
315 clickItem(items[1])
316 compare(historyEntryClickedSpy.count, 2)
317 compare(historyEntryClickedSpy.signalArguments[1][0], "http://example.org")
318
319 }
320
321 function test_activate_bookmarks_by_mouse() {
322 goToBookmarks()
323 var items = getListItems("bookmarksList", "bookmarkItem")
324 clickItem(items[0])
325 compare(bookmarkClickedSpy.count, 1)
326 compare(bookmarkClickedSpy.signalArguments[0][0], homepage)
327
328 clickItem(items[1])
329 compare(bookmarkClickedSpy.count, 2)
330 compare(bookmarkClickedSpy.signalArguments[1][0], "http://example.com")
331 }
332
333 function test_switch_folders_by_mouse() {
334 goToBookmarks()
335 var folders = getListItems("foldersList", "folderItem")
336
337 clickItem(folders[1])
338 var items = getListItems("bookmarksList", "bookmarkItem")
339 compare(items[0].title, "Example Net B")
340 compare(items[1].title, "Example Net A")
341 compare(items.length, 2)
342
343 clickItem(folders[0])
344 items = getListItems("bookmarksList", "bookmarkItem")
345 compare(items[0].url, homepage)
346 compare(items[1].title, "Example Com")
347 compare(items.length, 2)
348 }
349
350 function test_remove_bookmarks_by_keyboard() {
351 goToBookmarks()
352 keyClick(Qt.Key_Right)
353 var items = getListItems("bookmarksList", "bookmarkItem")
354
355 // verify that trying to delete the homepage bookmark does not work
356 keyClick(Qt.Key_Delete)
357 compare(bookmarkRemovedSpy.count, 0)
358
359 keyClick(Qt.Key_Down)
360 keyClick(Qt.Key_Delete)
361 compare(bookmarkRemovedSpy.count, 1)
362 compare(bookmarkRemovedSpy.signalArguments[0][0], items[1].url)
363 }
364
365 function test_remove_top_sites_by_keyboard() {
366 var previous = getListItems("topSitesList", "topSiteItem")
367 keyClick(Qt.Key_Delete)
368 var items = getListItems("topSitesList", "topSiteItem")
369 compare(previous.length - 1, items.length)
370 }
371 }
372}
0373
=== modified file 'tests/unittests/qml/tst_QmlTests.cpp'
--- tests/unittests/qml/tst_QmlTests.cpp 2015-06-25 17:54:01 +0000
+++ tests/unittests/qml/tst_QmlTests.cpp 2015-08-12 13:42:27 +0000
@@ -25,10 +25,16 @@
25#include <QtQuickTest/QtQuickTest>25#include <QtQuickTest/QtQuickTest>
2626
27// local27// local
28#include "bookmarks-model.h"
29#include "bookmarks-folderlist-model.h"
28#include "favicon-fetcher.h"30#include "favicon-fetcher.h"
29#include "file-operations.h"31#include "file-operations.h"
32#include "history-model.h"
33#include "history-timeframe-model.h"
34#include "limit-proxy-model.h"
30#include "searchengine.h"35#include "searchengine.h"
31#include "tabs-model.h"36#include "tabs-model.h"
37#include "top-sites-model.h"
3238
33static QObject* FileOperations_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine)39static QObject* FileOperations_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine)
34{40{
@@ -116,6 +122,12 @@
116 const char* browserUri = "webbrowserapp.private";122 const char* browserUri = "webbrowserapp.private";
117 qmlRegisterType<SearchEngine>(browserUri, 0, 1, "SearchEngine");123 qmlRegisterType<SearchEngine>(browserUri, 0, 1, "SearchEngine");
118 qmlRegisterType<TabsModel>(browserUri, 0, 1, "TabsModel");124 qmlRegisterType<TabsModel>(browserUri, 0, 1, "TabsModel");
125 qmlRegisterType<BookmarksModel>(browserUri, 0, 1, "BookmarksModel");
126 qmlRegisterType<BookmarksFolderListModel>(browserUri, 0, 1, "BookmarksFolderListModel");
127 qmlRegisterType<HistoryModel>(browserUri, 0, 1, "HistoryModel");
128 qmlRegisterType<HistoryTimeframeModel>(browserUri, 0, 1, "HistoryTimeframeModel");
129 qmlRegisterType<LimitProxyModel>(browserUri, 0, 1, "LimitProxyModel");
130 qmlRegisterType<TopSitesModel>(browserUri, 0, 1, "TopSitesModel");
119 qmlRegisterSingletonType<FileOperations>(browserUri, 0, 1, "FileOperations", FileOperations_singleton_factory);131 qmlRegisterSingletonType<FileOperations>(browserUri, 0, 1, "FileOperations", FileOperations_singleton_factory);
120132
121 qmlRegisterSingletonType<TestContext>("webbrowsertest.private", 0, 1, "TestContext", TestContext_singleton_factory);133 qmlRegisterSingletonType<TestContext>("webbrowsertest.private", 0, 1, "TestContext", TestContext_singleton_factory);

Subscribers

People subscribed via source and target branches

to status/vote changes: