Merge lp:~elopio/webbrowser-app/test_add_bookmark into lp:webbrowser-app

Proposed by Leo Arias
Status: Rejected
Rejected by: Olivier Tilloy
Proposed branch: lp:~elopio/webbrowser-app/test_add_bookmark
Merge into: lp:webbrowser-app
Prerequisite: lp:~elopio/webbrowser-app/copyright
Diff against target: 265 lines (+178/-4)
4 files modified
src/app/webbrowser/ActivityView.qml (+4/-2)
src/app/webbrowser/PageDelegate.qml (+2/-1)
tests/autopilot/webbrowser_app/emulators/browser.py (+132/-1)
tests/autopilot/webbrowser_app/tests/test_bookmarks.py (+40/-0)
To merge this branch: bzr merge lp:~elopio/webbrowser-app/test_add_bookmark
Reviewer Review Type Date Requested Status
Olivier Tilloy Disapprove
Leo Arias (community) Disapprove
PS Jenkins bot continuous-integration Needs Fixing
Javier Collado (community) Approve
Richard Huddie Pending
Víctor R. Ruiz Pending
Review via email: mp+205080@code.launchpad.net

Commit message

Added a test to add a bookmark.

To post a comment you must log in.
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: Approve (continuous-integration)
Revision history for this message
Javier Collado (javier.collado) wrote :

I've been able to run the test case successfully in my laptop. However, there
are a few minor problems that should be fixed:

- Indentation in the ActivityView class

$ flake8 browser.py
browser.py:146:6: E111 indentation is not a multiple of four
browser.py:147:10: E111 indentation is not a multiple of four
browser.py:150:10: E111 indentation is not a multiple of four
browser.py:152:6: E111 indentation is not a multiple of four
browser.py:153:10: E111 indentation is not a multiple of four
browser.py:154:10: E111 indentation is not a multiple of four
browser.py:156:6: E111 indentation is not a multiple of four
browser.py:157:10: E111 indentation is not a multiple of four
browser.py:158:10: E111 indentation is not a multiple of four

- URL formatting in exceptions:

%r should be replaced with {!r} to use .format (instead %), that is this:

raise BrowserEmulatorException(
    'The page with URL %r is not open.'.format(url))

shoud be written like this:

raise BrowserEmulatorException(
    'The page with URL {!r} is not open.'.format(url))

I still need to better understand the code, but these are the issues I've seen
so far.

review: Needs Fixing
Revision history for this message
Javier Collado (javier.collado) wrote :

I'm curious about the sorting of the PageDelegate objects. Why is it a good
choice to order them by the x coordinate?

In the test case being added by this request there's only one bookmark, so only
one PageDelegate, but I guess this is relevant for some other tests.

Finally, regading the sort itself, you might want to consider using the
attrgetter function as explained here:
https://wiki.python.org/moin/HowTo/Sorting#Operator_Module_Functions

That would turn this:
pages.sort(key=lambda page: page.x)

into this:
from operator import attrgetter
...
pages.sort(key=attrgetter('x'))

Not a big time saver for just one attribute, but is good to know if multiple
attributes are needed.

Revision history for this message
Leo Arias (elopio) wrote :

Thanks Javier!

> - Indentation in the ActivityView class
>
> $ flake8 browser.py

Fixed.

> - URL formatting in exceptions:

Fixed.

Revision history for this message
Leo Arias (elopio) wrote :

> I'm curious about the sorting of the PageDelegate objects. Why is it a good
> choice to order them by the x coordinate?
>
> In the test case being added by this request there's only one bookmark, so
> only
> one PageDelegate, but I guess this is relevant for some other tests.

Here I just copied an existing method to a better place. After this branch is reviewed, I'll propose another one that refactors the tests that use it, so I can remove the duplication. I forgot to mention about it, sorry.

There are some tests that use this method after adding an extra tab. So there are two pages, and we would like to know which one was added last. As they are in an horizontal list but we can't trust on the order of the objects returned by autopilot, the x coordinate tells us the order.

This needs to be implemented in the toolkit. We need a list iterator that returns the elements in the order they are displayed. But I'm blocked with 3 branches on the toolkit and 4 on autopilot, so that will have to wait a little.

> pages.sort(key=attrgetter('x'))

I didn't know about that. I made the change.

Thank you Javier!

Revision history for this message
Javier Collado (javier.collado) wrote :

Thanks for the updates.

I followed the code execution path and looked good to me. The only thing that
looks odd to me is:
self.main_window.open_activity() returns an ActivityView object
activity.open_bookmarks_tab() returns a BookmarksView object

but:
activity.open_activity_tab() returns a TimelineView object

I guess this would be less confusing if open_activity_tab method was renamed to
open_timeline_tab.

Aside from that, I ran this multiple times and the cleanup method worked fine,
so I'm fine with these changes.

review: Approve
Revision history for this message
Leo Arias (elopio) wrote :

Yes, I didn't find a good way to solve that. I'm trying to keep the user language, so all the methods are called as things the user can do with the UI. On the UI, there's nothing that says timeline. The timeline is the Activity tab inside the Activity page. So a user opens the activity page, and then can go either to the activity tab or to the browser tab.

I think the fact that's confusing while reading the tests means that it's confusing for an user.
Wouldn't it be better if we change activity tab label to say time line? I guess we need to ask designers about this.

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 :

FAILED: Continuous integration, rev:453
http://jenkins.qa.ubuntu.com/job/webbrowser-app-ci/600/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/2980
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2712/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-amd64-ci/102
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-armhf-ci/102
        deb: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-armhf-ci/102/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-i386-ci/102
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2619
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/2982
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/2982/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2713
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2713/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5136/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3714

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/webbrowser-app-ci/600/rebuild

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

Is there a reason for this branch to depend on lp:~elopio/webbrowser-app/copyright?

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

34 + Tabs {

Tabs inside Tabs? That doesn’t look right…

review: Needs Fixing
Revision history for this message
Leo Arias (elopio) wrote :

> 34 + Tabs {
>
> Tabs inside Tabs? That doesn’t look right…

It's Tab elements inside a Tabs element. That's how they do it on the toolkit example:
http://bazaar.launchpad.net/~ubuntu-sdk-team/ubuntu-ui-toolkit/trunk/view/head:/modules/Ubuntu/Components/Tabs.qml

But more importantly, the Tabs element has a property that's the currently selected tab index. We need that in order to select a tab from autopilot.

Revision history for this message
Leo Arias (elopio) wrote :

> Is there a reason for this branch to depend on lp:~elopio/webbrowser-
> app/copyright?

Huh, I just wanted to avoid a possible conflict with myself while changing the copyright year on this branch. Then I forgot to update the headers.
Now I've done it, and it seems the branches will not conflict. But still, it doesn't hurt to keep the prerequisite, right?

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

> > 34 + Tabs {
> >
> > Tabs inside Tabs? That doesn’t look right…
>
> It's Tab elements inside a Tabs element. That's how they do it on the toolkit
> example:
> http://bazaar.launchpad.net/~ubuntu-sdk-team/ubuntu-ui-
> toolkit/trunk/view/head:/modules/Ubuntu/Components/Tabs.qml
>
> But more importantly, the Tabs element has a property that's the currently
> selected tab index. We need that in order to select a tab from autopilot.

What I meant is that the top-level item of ActivityView is already a Tabs, and you added another Tabs as a child, I don’t think this is correct (nor needed).

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

> > Is there a reason for this branch to depend on lp:~elopio/webbrowser-
> > app/copyright?
>
> Huh, I just wanted to avoid a possible conflict with myself while changing the
> copyright year on this branch. Then I forgot to update the headers.
> Now I've done it, and it seems the branches will not conflict. But still, it
> doesn't hurt to keep the prerequisite, right?

No it doesn’t hurt indeed, it was simply curious about it.

Revision history for this message
Leo Arias (elopio) wrote :

> What I meant is that the top-level item of ActivityView is already a Tabs, and
> you added another Tabs as a child, I don’t think this is correct (nor needed).

You are right! I must have been drunk.
Back to work in progress to fix it tomorrow.

Thanks for the review.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:456
http://jenkins.qa.ubuntu.com/job/webbrowser-app-ci/612/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3676
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/3275/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-amd64-ci/114
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-armhf-ci/114
        deb: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-armhf-ci/114/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-trusty-i386-ci/114
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/3229
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3681
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3681/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/3277
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/3277/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5648/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/4488

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/webbrowser-app-ci/612/rebuild

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
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Leo Arias (elopio) wrote :

This is failing because of a bad timing coincidence.
I'm proposing a fix here:
https://code.launchpad.net/~elopio/ubuntu-ui-toolkit/tab_selection_timing/+merge/210219

This branch shouldn't land until that one is released. Other wise we might get errors like this one some times.

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
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

Thanks for improving the test coverage!
With the re-design of the browser app happening now, the entire activity view is going away, so I’m kind of reluctant to merging this now as it will have to be entirely rewritten very soon.
If there are general improvements that can be extracted from this branch and applied to the existing tests, I’d gladly take them in though.

Revision history for this message
Leo Arias (elopio) wrote :

I'll wait for the new bookmarks UI and adapt this branch then.

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

The new UI (phase 1) has landed, with a new way of managing bookmarks, and I made sure the functionality comes with autopilot tests from the start, so this branch isn’t needed anymore. Thanks Leo for your work on it.

review: Disapprove
Revision history for this message
Leo Arias (elopio) wrote :

Nice, thanks!

Unmerged revisions

459. By Leo Arias

Merged with trunk.

458. By Leo Arias

Removed the unnecesary override.

457. By Leo Arias

Fixed the Tabs mess.

456. By Leo Arias

Removed the extra Tabs.

455. By Leo Arias

Typo.

454. By Leo Arias

Updated copyright.

453. By Leo Arias

Use operator.attrgetter.

452. By Leo Arias

Fixed string format.

451. By Leo Arias

Fixed identation.

450. By Leo Arias

Rename.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/app/webbrowser/ActivityView.qml'
--- src/app/webbrowser/ActivityView.qml 2014-03-12 22:45:12 +0000
+++ src/app/webbrowser/ActivityView.qml 2014-04-25 02:58:59 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2013 Canonical Ltd.2 * Copyright 2013, 2014 Canonical Ltd.
3 *3 *
4 * This file is part of webbrowser-app.4 * This file is part of webbrowser-app.
5 *5 *
@@ -21,6 +21,7 @@
2121
22Tabs {22Tabs {
23 id: activityView23 id: activityView
24 objectName: "activityViewTabs"
2425
25 property alias tabsModel: timelineView.tabsModel26 property alias tabsModel: timelineView.tabsModel
26 property alias historyModel: timelineView.historyModel27 property alias historyModel: timelineView.historyModel
@@ -34,6 +35,7 @@
3435
35 Tab {36 Tab {
36 title: i18n.tr("Activity")37 title: i18n.tr("Activity")
38 objectName: "activityTab"
37 page: Page {39 page: Page {
38 TimelineView {40 TimelineView {
39 id: timelineView41 id: timelineView
@@ -49,9 +51,9 @@
49 }51 }
50 }52 }
51 }53 }
52
53 Tab {54 Tab {
54 title: i18n.tr("Bookmarks")55 title: i18n.tr("Bookmarks")
56 objectName: "bookmarksTab"
55 page: Page {57 page: Page {
56 BookmarksView {58 BookmarksView {
57 id: bookmarksView59 id: bookmarksView
5860
=== modified file 'src/app/webbrowser/PageDelegate.qml'
--- src/app/webbrowser/PageDelegate.qml 2014-03-12 22:45:12 +0000
+++ src/app/webbrowser/PageDelegate.qml 2014-04-25 02:58:59 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2013 Canonical Ltd.2 * Copyright 2013, 2014 Canonical Ltd.
3 *3 *
4 * This file is part of webbrowser-app.4 * This file is part of webbrowser-app.
5 *5 *
@@ -65,6 +65,7 @@
6565
66 Image {66 Image {
67 id: starIcon67 id: starIcon
68 objectName: "bookmarkImage"
68 source: pageDelegate.bookmarked ? "assets/browser_favourite_on.png"69 source: pageDelegate.bookmarked ? "assets/browser_favourite_on.png"
69 : "assets/browser_favourite_off.png"70 : "assets/browser_favourite_off.png"
70 visible: pageDelegate.canBookmark71 visible: pageDelegate.canBookmark
7172
=== modified file 'tests/autopilot/webbrowser_app/emulators/browser.py'
--- tests/autopilot/webbrowser_app/emulators/browser.py 2014-02-06 04:31:01 +0000
+++ tests/autopilot/webbrowser_app/emulators/browser.py 2014-04-25 02:58:59 +0000
@@ -1,6 +1,6 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#2#
3# Copyright 2013 Canonical3# Copyright 2013, 2014 Canonical
4#4#
5# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -14,9 +14,21 @@
14# You should have received a copy of the GNU General Public License14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.15# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17import logging
18import operator
19
20from autopilot import logging as autopilot_logging
21
17from ubuntuuitoolkit import emulators as uitk22from ubuntuuitoolkit import emulators as uitk
1823
1924
25logger = logging.getLogger(__name__)
26
27
28class BrowserEmulatorException(uitk.ToolkitEmulatorException):
29 """Exception raised when there is an error with the emulator."""
30
31
20class Panel(uitk.Toolbar):32class Panel(uitk.Toolbar):
21 pass33 pass
2234
@@ -27,6 +39,15 @@
27 An emulator class that makes it easy to interact with the webbrowser app.39 An emulator class that makes it easy to interact with the webbrowser app.
28 """40 """
2941
42 def get_tabs(self):
43 """Return the Tabs emualtor of the MainView.
44
45 Overriden because on the browser the Tabs container gets the
46 ActivityView name.
47
48 """
49 return self.select_single(ActivityView)
50
30 def get_toolbar(self):51 def get_toolbar(self):
31 # Overridden since the browser doesn’t use the MainView’s Toolbar.52 # Overridden since the browser doesn’t use the MainView’s Toolbar.
32 return self.select_single(Panel)53 return self.select_single(Panel)
@@ -101,3 +122,113 @@
101 tabs = view.select_many("PageDelegate", objectName="openTabDelegate")122 tabs = view.select_many("PageDelegate", objectName="openTabDelegate")
102 tabs.sort(key=lambda tab: tab.x)123 tabs.sort(key=lambda tab: tab.x)
103 return tabs124 return tabs
125
126 @autopilot_logging.log_action(logger.info)
127 def open_activity(self):
128 """Open the Activity view."""
129 if self.activityViewVisible:
130 logger.debug('The activity view is already opened.')
131 else:
132 toolbar = self.open_toolbar()
133 toolbar.click_button('activityButton')
134 self.activityViewVisible.wait_for(True)
135 return self.select_single(ActivityView)
136
137
138class ActivityView(uitk.Tabs):
139
140 def __init__(self, *args):
141 super(ActivityView, self).__init__(*args)
142 # XXX we need a better way to keep reference to the main view.
143 # --elopio - 2014-01-31
144 self.main_view = self.get_root_instance().select_single(Browser)
145
146 def open_activity_tab(self):
147 self.main_view.switch_to_tab('activityTab')
148 return self.select_single(TimelineView)
149
150 def open_bookmarks_tab(self):
151 self.main_view.switch_to_tab('bookmarksTab')
152 return self.select_single(BookmarksView)
153
154
155class TimelineView(uitk.UbuntuUIToolkitEmulatorBase):
156
157 @autopilot_logging.log_action(logger.info)
158 def bookmark_page(self, url):
159 """Add a page to the bookmarks.
160
161 :parameter url: The URL of the page to bookmark.
162 :raises BrowserEmulatorException: if the page is not in the currently
163 viewing list.
164
165 """
166 pages = self._get_currently_viewing_page_delegates()
167 for page in pages:
168 if page.url == url:
169 page.bookmark()
170 break
171 else:
172 raise BrowserEmulatorException(
173 'The page with URL {!r} is not open.'.format(url))
174
175 def _get_currently_viewing_page_delegates(self):
176 tabs_list = self.select_single('TabsList')
177 pages = tabs_list.select_many(
178 PageDelegate, objectName='openTabDelegate')
179 pages.sort(key=lambda page: page.x)
180 return pages
181
182
183class PageDelegate(uitk.UbuntuUIToolkitEmulatorBase):
184
185 def bookmark(self):
186 """Add this page to the bookmarks.
187
188 :raises BrowserEmulatorException: if the page is already bookmarked.
189
190 """
191 if self.bookmarked:
192 raise BrowserEmulatorException(
193 'The page with URL {!r} is already bookmarked.'.format(
194 self.url))
195 else:
196 bookmark_image = self.select_single(
197 'QQuickImage', objectName='bookmarkImage')
198 self.pointing_device.click_object(bookmark_image)
199 self.bookmarked.wait_for(True)
200
201 def remove_bookmark(self):
202 """Remove this page from the bookmarks.
203
204 :raises BrowserEmulatorException: if the page is not bookmarked.
205
206 """
207 if not self.bookmarked:
208 raise BrowserEmulatorException(
209 'The page with URL {!r} is not bookmarked.'.format(self.url))
210 else:
211 bookmark_image = self.select_single(
212 'QQuickImage', objectName='bookmarkImage')
213 self.pointing_device.click_object(bookmark_image)
214 # We can't just wait for the bookmarked value to be False, because
215 # on the Bookmarks view the element is removed. The check is left
216 # to the caller.
217
218
219class BookmarksView(uitk.UbuntuUIToolkitEmulatorBase):
220
221 def get_bookmarked_pages(self):
222 """Return a list with the URLs of the bookmarked pages."""
223 pages = self._get_bookmarked_page_delegates()
224 return [page.url for page in pages]
225
226 def _get_bookmarked_page_delegates(self):
227 pages = self.select_many(PageDelegate)
228 pages.sort(key=operator.attrgetter('x'))
229 return pages
230
231 def remove_all_bookmarks(self):
232 for page in self._get_bookmarked_page_delegates():
233 page.remove_bookmark()
234 page.wait_until_destroyed()
104235
=== added file 'tests/autopilot/webbrowser_app/tests/test_bookmarks.py'
--- tests/autopilot/webbrowser_app/tests/test_bookmarks.py 1970-01-01 00:00:00 +0000
+++ tests/autopilot/webbrowser_app/tests/test_bookmarks.py 2014-04-25 02:58:59 +0000
@@ -0,0 +1,40 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright 2014 Canonical
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17from webbrowser_app import tests
18
19from testtools.matchers import Contains
20
21
22class BookmarksTestCase(tests.StartOpenRemotePageTestCaseBase):
23
24 def setUp(self):
25 super(BookmarksTestCase, self).setUp()
26 self.addCleanup(self.remove_all_bookmarks)
27
28 def remove_all_bookmarks(self):
29 activity = self.main_window.open_activity()
30 bookmarks_tab = activity.open_bookmarks_tab()
31 bookmarks_tab.remove_all_bookmarks()
32
33 def test_bookmark_page_must_add_it_to_bookmarks_tab(self):
34 activity = self.main_window.open_activity()
35 activity_tab = activity.open_activity_tab()
36 activity_tab.bookmark_page(self.url)
37
38 bookmarks_tab = activity.open_bookmarks_tab()
39 self.assertThat(
40 bookmarks_tab.get_bookmarked_pages(), Contains(self.url))

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: