Merge lp:~edwin-grubbs/launchpad/bug-495067-move-windmill-tests into lp:launchpad/db-devel
- bug-495067-move-windmill-tests
- Merge into db-devel
Proposed by
Edwin Grubbs
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~edwin-grubbs/launchpad/bug-495067-move-windmill-tests |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
1455 lines (+699/-452) 18 files modified
database/schema/security.cfg (+3/-0) lib/canonical/launchpad/javascript/lp/comment.js (+0/-1) lib/canonical/launchpad/windmill/testing/widgets.py (+5/-3) lib/lp/code/browser/codereviewcomment.py (+4/-3) lib/lp/code/templates/branchmergeproposal-index.pt (+62/-27) lib/lp/registry/browser/product.py (+1/-1) lib/lp/registry/browser/team.py (+4/-2) lib/lp/registry/templates/milestone-index.pt (+2/-2) lib/lp/registry/templates/product-new.pt (+1/-1) lib/lp/registry/windmill/tests/test_add_milestone.py (+86/-87) lib/lp/registry/windmill/tests/test_datetime_picker.py (+70/-52) lib/lp/registry/windmill/tests/test_plusnew_step1.py (+65/-41) lib/lp/registry/windmill/tests/test_plusnew_step2.py (+90/-61) lib/lp/registry/windmill/tests/test_product.py (+43/-21) lib/lp/registry/windmill/tests/test_product_edit_people.py (+38/-17) lib/lp/registry/windmill/tests/test_project_licenses.py (+144/-124) lib/lp/registry/windmill/tests/test_timeline_graph.py (+6/-0) lib/lp/translations/tests/test_translationimportqueue.py (+75/-9) |
To merge this branch: | bzr merge lp:~edwin-grubbs/launchpad/bug-495067-move-windmill-tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Curtis Hovey (community) | code | Approve | |
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Edwin Grubbs (edwin-grubbs) wrote : | # |
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Curtis Hovey (sinzui) wrote : | # |
This must have been to most boring diff I have ever read.
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'database/schema/security.cfg' | |||
2 | --- database/schema/security.cfg 2009-12-02 13:08:18 +0000 | |||
3 | +++ database/schema/security.cfg 2009-12-11 20:25:26 +0000 | |||
4 | @@ -1216,6 +1216,9 @@ | |||
5 | 1216 | public.libraryfilecontent = SELECT, INSERT | 1216 | public.libraryfilecontent = SELECT, INSERT |
6 | 1217 | 1217 | ||
7 | 1218 | # rosetta auto imports | 1218 | # rosetta auto imports |
8 | 1219 | public.pofile = SELECT | ||
9 | 1220 | public.potemplate = SELECT | ||
10 | 1221 | public.translationgroup = SELECT | ||
11 | 1219 | public.translationimportqueueentry = SELECT, INSERT, UPDATE | 1222 | public.translationimportqueueentry = SELECT, INSERT, UPDATE |
12 | 1220 | 1223 | ||
13 | 1221 | # Closing bugs. | 1224 | # Closing bugs. |
14 | 1222 | 1225 | ||
15 | === modified file 'lib/canonical/launchpad/javascript/lp/comment.js' | |||
16 | --- lib/canonical/launchpad/javascript/lp/comment.js 2009-11-26 19:54:52 +0000 | |||
17 | +++ lib/canonical/launchpad/javascript/lp/comment.js 2009-12-11 20:25:26 +0000 | |||
18 | @@ -361,7 +361,6 @@ | |||
19 | 361 | }, | 361 | }, |
20 | 362 | renderUI: function() { | 362 | renderUI: function() { |
21 | 363 | CodeReviewComment.superclass.renderUI.apply(this); | 363 | CodeReviewComment.superclass.renderUI.apply(this); |
22 | 364 | Y.one('#inline-add-comment').setStyle('display', 'block'); | ||
23 | 365 | }, | 364 | }, |
24 | 366 | /** | 365 | /** |
25 | 367 | * Implementation of Widget.bindUI: Bind events to methods. | 366 | * Implementation of Widget.bindUI: Bind events to methods. |
26 | 368 | 367 | ||
27 | === modified file 'lib/canonical/launchpad/windmill/testing/widgets.py' | |||
28 | --- lib/canonical/launchpad/windmill/testing/widgets.py 2009-10-29 14:23:16 +0000 | |||
29 | +++ lib/canonical/launchpad/windmill/testing/widgets.py 2009-12-11 20:25:26 +0000 | |||
30 | @@ -60,10 +60,10 @@ | |||
31 | 60 | * reloads and verifies that the new value sticked. | 60 | * reloads and verifies that the new value sticked. |
32 | 61 | """ | 61 | """ |
33 | 62 | client = WindmillTestClient(self.suite) | 62 | client = WindmillTestClient(self.suite) |
34 | 63 | client.open(url=self.url) | ||
35 | 63 | 64 | ||
36 | 64 | self.user.ensure_login(client) | 65 | self.user.ensure_login(client) |
37 | 65 | 66 | ||
38 | 66 | client.open(url=self.url) | ||
39 | 67 | client.waits.forPageLoad(timeout=constants.PAGE_LOAD) | 67 | client.waits.forPageLoad(timeout=constants.PAGE_LOAD) |
40 | 68 | widget_base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id) | 68 | widget_base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id) |
41 | 69 | client.waits.forElement( | 69 | client.waits.forElement( |
42 | @@ -298,13 +298,15 @@ | |||
43 | 298 | 298 | ||
44 | 299 | def __call__(self): | 299 | def __call__(self): |
45 | 300 | client = WindmillTestClient(self.suite) | 300 | client = WindmillTestClient(self.suite) |
46 | 301 | self.user.ensure_login(client) | ||
47 | 302 | 301 | ||
48 | 303 | # Load page. | 302 | # Load page. |
49 | 304 | client.open(url=self.url) | 303 | client.open(url=self.url) |
51 | 305 | client.waits.forPageLoad(timeout=constants.PAGE_LOAD) | 304 | |
52 | 305 | self.user.ensure_login(client) | ||
53 | 306 | 306 | ||
54 | 307 | # Click on "Choose" link to show picker for the given field. | 307 | # Click on "Choose" link to show picker for the given field. |
55 | 308 | client.waits.forElement( | ||
56 | 309 | id=self.choose_link_id, timeout=constants.PAGE_LOAD) | ||
57 | 308 | client.click(id=self.choose_link_id) | 310 | client.click(id=self.choose_link_id) |
58 | 309 | 311 | ||
59 | 310 | # Search picker. | 312 | # Search picker. |
60 | 311 | 313 | ||
61 | === removed directory 'lib/canonical/launchpad/windmill/tests' | |||
62 | === removed file 'lib/canonical/launchpad/windmill/tests/__init__.py' | |||
63 | === removed directory 'lib/canonical/launchpad/windmill/tests/test_registry' | |||
64 | === removed file 'lib/canonical/launchpad/windmill/tests/test_registry/__init__.py' | |||
65 | === modified file 'lib/lp/code/browser/codereviewcomment.py' | |||
66 | --- lib/lp/code/browser/codereviewcomment.py 2009-10-29 23:51:08 +0000 | |||
67 | +++ lib/lp/code/browser/codereviewcomment.py 2009-12-11 20:25:26 +0000 | |||
68 | @@ -204,7 +204,7 @@ | |||
69 | 204 | 204 | ||
70 | 205 | class MyDropWidget(DropdownWidget): | 205 | class MyDropWidget(DropdownWidget): |
71 | 206 | "Override the default no-value display name to -Select-." | 206 | "Override the default no-value display name to -Select-." |
73 | 207 | _messageNoValue = '-Select-' | 207 | _messageNoValue = 'Comment only' |
74 | 208 | 208 | ||
75 | 209 | schema = IEditCodeReviewComment | 209 | schema = IEditCodeReviewComment |
76 | 210 | 210 | ||
77 | @@ -251,10 +251,11 @@ | |||
78 | 251 | @action('Save Comment', name='add') | 251 | @action('Save Comment', name='add') |
79 | 252 | def add_action(self, action, data): | 252 | def add_action(self, action, data): |
80 | 253 | """Create the comment...""" | 253 | """Create the comment...""" |
81 | 254 | vote = data.get('vote') | ||
82 | 255 | review_type = data.get('review_type') | ||
83 | 254 | comment = self.branch_merge_proposal.createComment( | 256 | comment = self.branch_merge_proposal.createComment( |
84 | 255 | self.user, subject=None, content=data['comment'], | 257 | self.user, subject=None, content=data['comment'], |
87 | 256 | parent=self.reply_to, vote=data['vote'], | 258 | parent=self.reply_to, vote=vote, review_type=review_type) |
86 | 257 | review_type=data['review_type']) | ||
88 | 258 | 259 | ||
89 | 259 | @property | 260 | @property |
90 | 260 | def next_url(self): | 261 | def next_url(self): |
91 | 261 | 262 | ||
92 | === modified file 'lib/lp/code/templates/branchmergeproposal-index.pt' | |||
93 | --- lib/lp/code/templates/branchmergeproposal-index.pt 2009-11-26 23:36:50 +0000 | |||
94 | +++ lib/lp/code/templates/branchmergeproposal-index.pt 2009-12-11 20:25:26 +0000 | |||
95 | @@ -21,6 +21,24 @@ | |||
96 | 21 | #commit-message, #edit-commit-message { | 21 | #commit-message, #edit-commit-message { |
97 | 22 | margin: 1em 0 0 0; | 22 | margin: 1em 0 0 0; |
98 | 23 | } | 23 | } |
99 | 24 | #add-comment-form { | ||
100 | 25 | max-width: 60em; | ||
101 | 26 | padding-bottom: 3em; | ||
102 | 27 | } | ||
103 | 28 | #add-comment-form textarea{ | ||
104 | 29 | width: 100%; | ||
105 | 30 | max-width: inherit; | ||
106 | 31 | } | ||
107 | 32 | #add-comment-form .actions { | ||
108 | 33 | float: right; | ||
109 | 34 | margin: 0 -0.5em; | ||
110 | 35 | } | ||
111 | 36 | #add-comment-review-fields { | ||
112 | 37 | margin-top: 1em; | ||
113 | 38 | } | ||
114 | 39 | #add-comment-review-fields div { | ||
115 | 40 | display: inline; | ||
116 | 41 | } | ||
117 | 24 | /* A page-specific fix for inline text are editing to line up box. */ | 42 | /* A page-specific fix for inline text are editing to line up box. */ |
118 | 25 | #edit-commit-message .yui-ieditor-input { top: 0; } | 43 | #edit-commit-message .yui-ieditor-input { top: 0; } |
119 | 26 | </style> | 44 | </style> |
120 | @@ -92,6 +110,12 @@ | |||
121 | 92 | </div> | 110 | </div> |
122 | 93 | 111 | ||
123 | 94 | <div class="yui-g"> | 112 | <div class="yui-g"> |
124 | 113 | <tal:not-logged-in condition="not: view/user"> | ||
125 | 114 | <div align="center" id="add-comment-login-first"> | ||
126 | 115 | To post a comment you must <a href="+login">log in</a>. | ||
127 | 116 | </div> | ||
128 | 117 | </tal:not-logged-in> | ||
129 | 118 | |||
130 | 95 | <div tal:define="link menu/add_comment" | 119 | <div tal:define="link menu/add_comment" |
131 | 96 | tal:condition="link/enabled" | 120 | tal:condition="link/enabled" |
132 | 97 | tal:content="structure link/render"> | 121 | tal:content="structure link/render"> |
133 | @@ -101,20 +125,27 @@ | |||
134 | 101 | <div id="conversation" | 125 | <div id="conversation" |
135 | 102 | tal:content="structure view/conversation/@@+render"/> | 126 | tal:content="structure view/conversation/@@+render"/> |
136 | 103 | </div> | 127 | </div> |
151 | 104 | <!-- Hide inline commenting if YUI isn't used. --> | 128 | |
152 | 105 | <div id="inline-add-comment" style="display: none"> | 129 | <tal:logged-in condition="view/user"> |
153 | 106 | <tal:comment replace="structure context/@@+comment/++form++" /> | 130 | <div tal:define="comment_form nocall:context/@@+comment; |
154 | 107 | <div class="actions" id="launchpad-form-actions"> | 131 | dummy comment_form/initialize"> |
155 | 108 | <input type="submit" id="field.actions.add" name="field.actions.add" value="Save Comment" class="button" /> | 132 | <h2 id="add-comment">Add comment</h2> |
156 | 109 | </div> | 133 | <form action="+comment" |
157 | 110 | </div> | 134 | method="post" |
158 | 111 | 135 | enctype="multipart/form-data" | |
159 | 112 | <script type="text/javascript"> | 136 | accept-charset="UTF-8" |
160 | 113 | LPS.use('lp.comment', function(Y) { | 137 | id="add-comment-form"> |
161 | 114 | var comment = new Y.lp.CodeReviewComment(); | 138 | <tal:comment-input replace="structure comment_form/widgets/comment"/> |
162 | 115 | comment.render(); | 139 | <div id="add-comment-review-fields"> |
163 | 116 | }) | 140 | Review: <tal:review replace="structure comment_form/widgets/vote"/> |
164 | 117 | </script> | 141 | Review type: <tal:review replace="structure comment_form/widgets/review_type"/> |
165 | 142 | <div class="actions" | ||
166 | 143 | tal:content="structure comment_form/actions/field.actions.add/render" /> | ||
167 | 144 | </div> | ||
168 | 145 | </form> | ||
169 | 146 | </div> | ||
170 | 147 | </tal:logged-in> | ||
171 | 148 | |||
172 | 118 | <div class="yui-g"> | 149 | <div class="yui-g"> |
173 | 119 | <div class="yui-u first"> | 150 | <div class="yui-u first"> |
174 | 120 | <div id="source-revisions" | 151 | <div id="source-revisions" |
175 | @@ -159,21 +190,25 @@ | |||
176 | 159 | string:<script id='codereview-script' type='text/javascript'>" /> | 190 | string:<script id='codereview-script' type='text/javascript'>" /> |
177 | 160 | conf = <tal:status-config replace="view/status_config" /> | 191 | conf = <tal:status-config replace="view/status_config" /> |
178 | 161 | <!-- | 192 | <!-- |
180 | 162 | LPS.use('io-base', 'code.codereview', 'code.branchmergeproposal', | 193 | LPS.use('io-base', 'code.codereview', 'code.branchmergeproposal', 'lp.comment', |
181 | 163 | function(Y) { | 194 | function(Y) { |
182 | 164 | 195 | ||
195 | 165 | 196 | Y.on('load', function() { | |
196 | 166 | if(Y.UA.ie) { | 197 | var logged_in = LP.client.links['me'] !== undefined; |
197 | 167 | return; | 198 | |
198 | 168 | } | 199 | if (logged_in) { |
199 | 169 | 200 | var comment = new Y.lp.CodeReviewComment(); | |
200 | 170 | Y.on('domready', function() { | 201 | comment.render(); |
201 | 171 | Y.code.codereview.connect_links(); | 202 | |
202 | 172 | Y.code.branchmergeproposal.connect_status(conf); | 203 | if(Y.UA.ie) { |
203 | 173 | }); | 204 | return; |
204 | 174 | 205 | } | |
205 | 175 | (new Y.codereview.NumberToggle()).render(); | 206 | |
206 | 176 | 207 | Y.code.codereview.connect_links(); | |
207 | 208 | Y.code.branchmergeproposal.connect_status(conf); | ||
208 | 209 | } | ||
209 | 210 | (new Y.codereview.NumberToggle()).render(); | ||
210 | 211 | }, window); | ||
211 | 177 | }); | 212 | }); |
212 | 178 | --> | 213 | --> |
213 | 179 | <tal:script replace="structure string:</script>" /> | 214 | <tal:script replace="structure string:</script>" /> |
214 | 180 | 215 | ||
215 | === modified file 'lib/lp/registry/browser/product.py' | |||
216 | --- lib/lp/registry/browser/product.py 2009-12-05 18:37:28 +0000 | |||
217 | +++ lib/lp/registry/browser/product.py 2009-12-11 20:25:26 +0000 | |||
218 | @@ -778,7 +778,7 @@ | |||
219 | 778 | **additional_arguments) | 778 | **additional_arguments) |
220 | 779 | self.show_programming_languages = bool( | 779 | self.show_programming_languages = bool( |
221 | 780 | self.context.programminglang or | 780 | self.context.programminglang or |
223 | 781 | self.user == self.context.owner) | 781 | check_permission('launchpad.Edit', self.context)) |
224 | 782 | 782 | ||
225 | 783 | @property | 783 | @property |
226 | 784 | def show_license_status(self): | 784 | def show_license_status(self): |
227 | 785 | 785 | ||
228 | === modified file 'lib/lp/registry/browser/team.py' | |||
229 | --- lib/lp/registry/browser/team.py 2009-12-01 22:09:05 +0000 | |||
230 | +++ lib/lp/registry/browser/team.py 2009-12-11 20:25:26 +0000 | |||
231 | @@ -901,7 +901,6 @@ | |||
232 | 901 | return None | 901 | return None |
233 | 902 | 902 | ||
234 | 903 | 903 | ||
235 | 904 | |||
236 | 905 | class ProposedTeamMembersEditView(LaunchpadFormView): | 904 | class ProposedTeamMembersEditView(LaunchpadFormView): |
237 | 906 | schema = Interface | 905 | schema = Interface |
238 | 907 | label = 'Proposed team members' | 906 | label = 'Proposed team members' |
239 | @@ -915,7 +914,10 @@ | |||
240 | 915 | status = TeamMembershipStatus.APPROVED | 914 | status = TeamMembershipStatus.APPROVED |
241 | 916 | elif action == "decline": | 915 | elif action == "decline": |
242 | 917 | status = TeamMembershipStatus.DECLINED | 916 | status = TeamMembershipStatus.DECLINED |
244 | 918 | elif action == "hold": | 917 | else: |
245 | 918 | # The action is "hold" or no action was specified for this | ||
246 | 919 | # person, which could happen if the set of proposed members | ||
247 | 920 | # changed while the form was being processed. | ||
248 | 919 | continue | 921 | continue |
249 | 920 | 922 | ||
250 | 921 | self.context.setMembershipData( | 923 | self.context.setMembershipData( |
251 | 922 | 924 | ||
252 | === modified file 'lib/lp/registry/templates/milestone-index.pt' | |||
253 | --- lib/lp/registry/templates/milestone-index.pt 2009-11-15 19:37:56 +0000 | |||
254 | +++ lib/lp/registry/templates/milestone-index.pt 2009-12-11 20:25:26 +0000 | |||
255 | @@ -53,12 +53,12 @@ | |||
256 | 53 | tal:condition="view/milestone/series_target" /></dd> | 53 | tal:condition="view/milestone/series_target" /></dd> |
257 | 54 | </dl> | 54 | </dl> |
258 | 55 | 55 | ||
260 | 56 | <dl> | 56 | <dl id="version"> |
261 | 57 | <dt>Version:</dt> | 57 | <dt>Version:</dt> |
262 | 58 | <dd><tal:version replace="context/name" /></dd> | 58 | <dd><tal:version replace="context/name" /></dd> |
263 | 59 | </dl> | 59 | </dl> |
264 | 60 | 60 | ||
266 | 61 | <dl> | 61 | <dl id="code-name"> |
267 | 62 | <dt>Code name:</dt> | 62 | <dt>Code name:</dt> |
268 | 63 | <dd> | 63 | <dd> |
269 | 64 | <tal:code-name replace="view/milestone/code_name" /> | 64 | <tal:code-name replace="view/milestone/code_name" /> |
270 | 65 | 65 | ||
271 | === modified file 'lib/lp/registry/templates/product-new.pt' | |||
272 | --- lib/lp/registry/templates/product-new.pt 2009-12-03 18:33:22 +0000 | |||
273 | +++ lib/lp/registry/templates/product-new.pt 2009-12-11 20:25:26 +0000 | |||
274 | @@ -100,7 +100,7 @@ | |||
275 | 100 | url_field.on('keyup', function(e) { | 100 | url_field.on('keyup', function(e) { |
276 | 101 | if (url_field.get('value') == '') { | 101 | if (url_field.get('value') == '') { |
277 | 102 | /* The user cleared the URL field; turn on autofill. */ | 102 | /* The user cleared the URL field; turn on autofill. */ |
279 | 103 | name_field.attach('keyup', autofill); | 103 | name_field.on('keyup', autofill); |
280 | 104 | } | 104 | } |
281 | 105 | else { | 105 | else { |
282 | 106 | /* Honor the user's URL; turn off autofill. */ | 106 | /* Honor the user's URL; turn off autofill. */ |
283 | 107 | 107 | ||
284 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_add_milestone.py' => 'lib/lp/registry/windmill/tests/test_add_milestone.py' | |||
285 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_add_milestone.py 2009-06-25 05:30:52 +0000 | |||
286 | +++ lib/lp/registry/windmill/tests/test_add_milestone.py 2009-12-11 20:25:26 +0000 | |||
287 | @@ -7,95 +7,94 @@ | |||
288 | 7 | __all__ = [] | 7 | __all__ = [] |
289 | 8 | 8 | ||
290 | 9 | import time | 9 | import time |
291 | 10 | import unittest | ||
292 | 10 | 11 | ||
293 | 11 | from canonical.launchpad.windmill.testing import lpuser | 12 | from canonical.launchpad.windmill.testing import lpuser |
294 | 12 | 13 | ||
295 | 13 | from windmill.authoring import WindmillTestClient | 14 | from windmill.authoring import WindmillTestClient |
296 | 14 | 15 | ||
384 | 15 | 16 | from lp.registry.windmill.testing import RegistryWindmillLayer | |
385 | 16 | class InlineAddMilestoneForReleaseTest: | 17 | from lp.testing import TestCaseWithFactory |
386 | 17 | """Test adding a milestone inline.""" | 18 | |
387 | 18 | 19 | ||
388 | 19 | def __init__(self, name=None, | 20 | def test_inline_add_milestone(client, url, name=None, suite='milestone', |
389 | 20 | url='http://launchpad.dev:8085/bzr/trunk/+addrelease', | 21 | user=lpuser.FOO_BAR): |
390 | 21 | suite='milestone', user=lpuser.FOO_BAR): | 22 | """Test the form overlay for adding a milestone. |
391 | 22 | """Create a new InlineAddMilestoneForReleaseTest. | 23 | |
392 | 23 | 24 | :param name: Name of the test. | |
393 | 24 | :param name: Name of the test. | 25 | :param url: Starting url. |
394 | 25 | :param url: Starting url. | 26 | :param suite: The suite in which this test is part of. |
395 | 26 | :param suite: The suite in which this test is part of. | 27 | :param user: The user who should be logged in. |
396 | 27 | :param user: The user who should be logged in. | 28 | """ |
397 | 28 | """ | 29 | # Ensure that the milestone name doesn't conflict with previous |
398 | 29 | self.url = url | 30 | # test runs, and test that it correctly lowercases the name. |
399 | 30 | if name is None: | 31 | milestone_name = u'FOObar%x' % int(time.time()) |
400 | 31 | self.__name__ = 'test_%s_add_milestone' % suite | 32 | code_name = u'code-%s' % milestone_name |
401 | 32 | else: | 33 | |
402 | 33 | self.__name__ = name | 34 | user.ensure_login(client) |
403 | 34 | self.suite = suite | 35 | client.open(url=url) |
404 | 35 | self.user = user | 36 | client.waits.forPageLoad(timeout=u'20000') |
405 | 36 | self.client = None | 37 | |
406 | 37 | 38 | client.waits.forElement( | |
407 | 38 | def __call__(self): | 39 | id=u'field.milestone_for_release', timeout=u'8000') |
408 | 39 | """Tests creating new milestone for a release.""" | 40 | |
409 | 40 | # Ensure that the milestone name doesn't conflict with previous | 41 | # Click the "Create milestone" link. |
410 | 41 | # test runs, and test that it correctly lowercases the name. | 42 | client.click(id=u'create-milestone-link') |
411 | 42 | milestone_name = u'FOObar%x' % int(time.time()) | 43 | |
412 | 43 | code_name = u'code-%s' % milestone_name | 44 | # Submit milestone form. |
413 | 44 | 45 | client.waits.forElement(id=u'field.name', timeout=u'8000') | |
414 | 45 | self.client = WindmillTestClient(self.suite) | 46 | client.type(id='field.name', text=milestone_name) |
415 | 46 | 47 | client.type(id='field.code_name', text=code_name) | |
416 | 47 | self.user.ensure_login(self.client) | 48 | client.type(id='field.dateexpected', text=u"2004-01-05") |
417 | 48 | self.client.open(url=self.url) | 49 | client.type(id='field.summary', text=u"foo bar") |
418 | 49 | self.client.waits.forPageLoad(timeout=u'20000') | 50 | client.click(id=u'formoverlay-add-milestone') |
419 | 50 | 51 | ||
420 | 51 | self.client.waits.forElement(id=u'field.milestone_for_release', | 52 | # Verify that the milestone was added to the SELECT input, |
421 | 52 | timeout=u'8000') | 53 | # and that it is now selected. |
422 | 53 | 54 | client.waits.sleep(milliseconds='1000') | |
423 | 54 | # Click the "Create milestone" link. | 55 | client.asserts.assertSelected(id="field.milestone_for_release", |
424 | 55 | self.client.click(id=u'create-milestone-link') | 56 | validator=milestone_name.lower()) |
425 | 56 | 57 | ||
426 | 57 | # Submit milestone form. | 58 | # Verify error message when trying to create a milestone with a |
427 | 58 | self.client.waits.forElement(id=u'field.name', timeout=u'8000') | 59 | # conflicting name. |
428 | 59 | self.client.type(id='field.name', text=milestone_name) | 60 | client.click(id=u'create-milestone-link') |
429 | 60 | self.client.type(id='field.code_name', text=code_name) | 61 | client.waits.forElement(id=u'field.name', timeout=u'8000') |
430 | 61 | self.client.type(id='field.dateexpected', text=u"2004-01-05") | 62 | client.type(id='field.name', text=milestone_name) |
431 | 62 | self.client.type(id='field.summary', text=u"foo bar") | 63 | client.click(id=u'formoverlay-add-milestone') |
432 | 63 | self.client.click(id=u'formoverlay-add-milestone') | 64 | client.asserts.assertTextIn( |
433 | 64 | 65 | classname='yui-lazr-formoverlay-errors', | |
434 | 65 | # Verify that the milestone was added to the SELECT input, | 66 | validator='The name %s is already used' % milestone_name.lower()) |
435 | 66 | # and that it is now selected. | 67 | client.click(classname='close-button') |
436 | 67 | self.client.waits.sleep(milliseconds='1000') | 68 | |
437 | 68 | self.client.asserts.assertSelected(id="field.milestone_for_release", | 69 | # Submit product release form. |
438 | 69 | validator=milestone_name.lower()) | 70 | client.select(id='field.milestone_for_release', |
439 | 70 | 71 | val=milestone_name.lower()) | |
440 | 71 | # Verify error message when trying to create a milestone with a | 72 | client.type(id='field.datereleased', text=u"2004-02-22") |
441 | 72 | # conflicting name. | 73 | client.click(id=u'field.actions.create') |
442 | 73 | self.client.click(id=u'create-milestone-link') | 74 | client.waits.forPageLoad(timeout=u'20000') |
443 | 74 | self.client.waits.forElement(id=u'field.name', timeout=u'8000') | 75 | |
444 | 75 | self.client.type(id='field.name', text=milestone_name) | 76 | # Verify that the release was created. |
445 | 76 | self.client.click(id=u'formoverlay-add-milestone') | 77 | client.waits.forElement(id="version") |
446 | 77 | self.client.asserts.assertText( | 78 | client.asserts.assertText( |
447 | 78 | id='milestone-error', | 79 | xpath="//*[@id='version']/dd", validator=milestone_name.lower()) |
448 | 79 | validator='The name %s is already used' % milestone_name.lower()) | 80 | client.asserts.assertText( |
449 | 80 | self.client.click(classname='close-button') | 81 | xpath="//*[@id='code-name']/dd", validator=code_name) |
450 | 81 | 82 | ||
451 | 82 | # Submit product release form. | 83 | |
452 | 83 | self.client.select(id='field.milestone_for_release', | 84 | class TestAddMilestone(TestCaseWithFactory): |
453 | 84 | val=milestone_name.lower()) | 85 | """Test form overlay widget for adding a milestone.""" |
454 | 85 | self.client.type(id='field.datereleased', text=u"2004-02-22") | 86 | |
455 | 86 | self.client.click(id=u'field.actions.create') | 87 | layer = RegistryWindmillLayer |
456 | 87 | self.client.waits.forPageLoad(timeout=u'20000') | 88 | |
457 | 88 | 89 | def setUp(self): | |
458 | 89 | # Verify that the release was created. | 90 | self.client = WindmillTestClient('AddMilestone') |
459 | 90 | milestone_xpath = ( | 91 | |
460 | 91 | "//table[@id='series_trunk']//a[@href='/bzr/+milestone/%s']" | 92 | def test_adding_milestone_on_addrelease_page(self): |
461 | 92 | % milestone_name.lower()) | 93 | test_inline_add_milestone( |
462 | 93 | self.client.waits.forElement(xpath=milestone_xpath, timeout=u'8000') | 94 | self.client, |
463 | 94 | self.client.asserts.assertText( | 95 | url='http://launchpad.dev:8085/bzr/trunk/+addrelease', |
464 | 95 | xpath=milestone_xpath, validator=milestone_name.lower()) | 96 | name='test_inline_add_milestone_for_release') |
465 | 96 | self.client.asserts.assertText( | 97 | |
466 | 97 | xpath=milestone_xpath, validator=code_name) | 98 | |
467 | 98 | 99 | def test_suite(): | |
468 | 99 | 100 | return unittest.TestLoader().loadTestsFromName(__name__) | |
382 | 100 | test_inline_add_milestone_for_release = InlineAddMilestoneForReleaseTest( | ||
383 | 101 | name='test_inline_add_milestone_for_release') | ||
469 | 102 | 101 | ||
470 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_datetime_picker.py' => 'lib/lp/registry/windmill/tests/test_datetime_picker.py' | |||
471 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_datetime_picker.py 2009-06-25 05:30:52 +0000 | |||
472 | +++ lib/lp/registry/windmill/tests/test_datetime_picker.py 2009-12-11 20:25:26 +0000 | |||
473 | @@ -6,57 +6,75 @@ | |||
474 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
475 | 7 | __all__ = [] | 7 | __all__ = [] |
476 | 8 | 8 | ||
477 | 9 | import unittest | ||
478 | 10 | |||
479 | 11 | from windmill.authoring import WindmillTestClient | ||
480 | 12 | |||
481 | 9 | from canonical.launchpad.windmill.testing import lpuser | 13 | from canonical.launchpad.windmill.testing import lpuser |
482 | 10 | 14 | ||
535 | 11 | from windmill.authoring import WindmillTestClient | 15 | from lp.registry.windmill.testing import RegistryWindmillLayer |
536 | 12 | 16 | from lp.testing import TestCaseWithFactory | |
537 | 13 | def test_datetime_calendar_widget(): | 17 | |
538 | 14 | """Test the calendar widget's general functionality. | 18 | |
539 | 15 | 19 | class TestDateTimeCalendarWidget(TestCaseWithFactory): | |
540 | 16 | This test ensures that, with Javascript enabled, an input field | 20 | """Test datetime calendar widget.""" |
541 | 17 | with the 'yui-calendar' class will get an extra 'choose...' link | 21 | |
542 | 18 | which opens up a calendar widget. The extra class 'withtime' is | 22 | layer = RegistryWindmillLayer |
543 | 19 | used to optionally include time fields. | 23 | |
544 | 20 | """ | 24 | def setUp(self): |
545 | 21 | client = WindmillTestClient("Datetime calendar widget test") | 25 | self.client = WindmillTestClient('DateTimeCalendarWidget') |
546 | 22 | lpuser.SAMPLE_PERSON.ensure_login(client) | 26 | |
547 | 23 | 27 | def test_datetime_calendar_widget(self): | |
548 | 24 | # Open a new sprint page and wait for it to finish loading. | 28 | """Test the calendar widget's general functionality. |
549 | 25 | client.open(url=u'http://blueprints.launchpad.dev:8085/sprints/+new') | 29 | |
550 | 26 | client.waits.forPageLoad(timeout=u'20000') | 30 | This test ensures that, with Javascript enabled, an input field |
551 | 27 | client.waits.forElement(link=u'Choose...', timeout=u'8000') | 31 | with the 'yui-calendar' class will get an extra 'choose...' link |
552 | 28 | 32 | which opens up a calendar widget. The extra class 'withtime' is | |
553 | 29 | # Enter a date directly in the field first (which will ensure | 33 | used to optionally include time fields. |
554 | 30 | # the calendar widget opens with this date.) | 34 | """ |
555 | 31 | client.click(id=u'field.time_starts') | 35 | lpuser.SAMPLE_PERSON.ensure_login(self.client) |
556 | 32 | client.type(text=u'2009-05-08 10:04', id=u'field.time_starts') | 36 | |
557 | 33 | 37 | # Open a new sprint page and wait for it to finish loading. | |
558 | 34 | # Open the calendar widget | 38 | self.client.open( |
559 | 35 | client.click(link=u'Choose...') | 39 | url=u'http://blueprints.launchpad.dev:8085/sprints/+new') |
560 | 36 | 40 | self.client.waits.forPageLoad(timeout=u'20000') | |
561 | 37 | # Initially choose the 21st of May 2009 and verify that the input | 41 | self.client.waits.forElement(link=u'Choose...', timeout=u'8000') |
562 | 38 | # field's value has changed. | 42 | |
563 | 39 | client.click(link=u'21') | 43 | # Enter a date directly in the field first (which will ensure |
564 | 40 | client.asserts.assertValue(validator=u'2009-05-21 10:04', | 44 | # the calendar widget opens with this date.) |
565 | 41 | id=u'field.time_starts') | 45 | self.client.click(id=u'field.time_starts') |
566 | 42 | 46 | self.client.type(text=u'2009-05-08 10:04', id=u'field.time_starts') | |
567 | 43 | # Navigate to the next month, select the 9th, enter a time of 10:30 | 47 | |
568 | 44 | # and click the close/confirm button, then verify the correct value | 48 | # Open the calendar widget |
569 | 45 | # is in the field. | 49 | self.client.click(link=u'Choose...') |
570 | 46 | client.click(link=u'Next Month (June 2009)') | 50 | |
571 | 47 | client.click(link=u'9') | 51 | # Initially choose the 21st of May 2009 and verify that the input |
572 | 48 | client.type( | 52 | # field's value has changed. |
573 | 49 | xpath=(u"//div[@id='calendar_container-field.time_starts']" | 53 | self.client.click(link=u'21') |
574 | 50 | u"/div[2]/input"), | 54 | self.client.asserts.assertValue( |
575 | 51 | text=u'10') | 55 | validator=u'2009-05-21 10:04', id=u'field.time_starts') |
576 | 52 | 56 | ||
577 | 53 | client.type( | 57 | # Navigate to the next month, select the 9th, enter a time of 10:30 |
578 | 54 | xpath=(u"//div[@id='calendar_container-field.time_starts']" | 58 | # and click the close/confirm button, then verify the correct value |
579 | 55 | u"/div[2]/input[2]"), | 59 | # is in the field. |
580 | 56 | text=u'30') | 60 | self.client.click(link=u'Next Month (June 2009)') |
581 | 57 | 61 | self.client.click(link=u'9') | |
582 | 58 | client.click(xpath=(u"//div[@id='calendar_container-field.time_starts']" | 62 | self.client.type( |
583 | 59 | u"/div[2]/button")) | 63 | xpath=(u"//div[@id='calendar_container-field.time_starts']" |
584 | 60 | client.asserts.assertValue(validator=u'2009-06-09 10:30', | 64 | u"/div[2]/input"), |
585 | 61 | id=u'field.time_starts') | 65 | text=u'10') |
586 | 62 | 66 | ||
587 | 67 | self.client.type( | ||
588 | 68 | xpath=(u"//div[@id='calendar_container-field.time_starts']" | ||
589 | 69 | u"/div[2]/input[2]"), | ||
590 | 70 | text=u'30') | ||
591 | 71 | |||
592 | 72 | self.client.click( | ||
593 | 73 | xpath=(u"//div[@id='calendar_container-field.time_starts']" | ||
594 | 74 | u"/div[2]/button")) | ||
595 | 75 | self.client.asserts.assertValue( | ||
596 | 76 | validator=u'2009-06-09 10:30', id=u'field.time_starts') | ||
597 | 77 | |||
598 | 78 | |||
599 | 79 | def test_suite(): | ||
600 | 80 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
601 | 63 | 81 | ||
602 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step1.py' => 'lib/lp/registry/windmill/tests/test_plusnew_step1.py' | |||
603 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step1.py 2009-06-25 05:30:52 +0000 | |||
604 | +++ lib/lp/registry/windmill/tests/test_plusnew_step1.py 2009-12-11 20:25:26 +0000 | |||
605 | @@ -1,48 +1,72 @@ | |||
606 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
607 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
608 | 3 | 3 | ||
609 | 4 | """Test form for creating a new project.""" | ||
610 | 5 | |||
611 | 6 | __metaclass__ = type | ||
612 | 7 | __all__ = [] | ||
613 | 8 | |||
614 | 9 | import unittest | ||
615 | 10 | |||
616 | 4 | from windmill.authoring import WindmillTestClient | 11 | from windmill.authoring import WindmillTestClient |
617 | 5 | 12 | ||
618 | 6 | from canonical.launchpad.windmill.testing import lpuser | 13 | from canonical.launchpad.windmill.testing import lpuser |
619 | 7 | 14 | ||
661 | 8 | 15 | from lp.registry.windmill.testing import RegistryWindmillLayer | |
662 | 9 | def test_projects_plusnew_text_fields(): | 16 | from lp.testing import TestCaseWithFactory |
663 | 10 | """Test the text fields on step 1 of projects/+new page. | 17 | |
664 | 11 | 18 | BACKSPACE = u'\x08' | |
665 | 12 | On step 1 of the wizard, the URL field gets autofilled from the Name | 19 | |
666 | 13 | field. Also, the URL field will not accept invalid characters. | 20 | |
667 | 14 | """ | 21 | class TestNewProjectStep1(TestCaseWithFactory): |
668 | 15 | client = WindmillTestClient('projects/+new step one dynamism') | 22 | """Test form for creating a new project.""" |
669 | 16 | lpuser.SAMPLE_PERSON.ensure_login(client) | 23 | |
670 | 17 | 24 | layer = RegistryWindmillLayer | |
671 | 18 | # Perform step 1 of the project registration, using information that will | 25 | |
672 | 19 | # yield search results. | 26 | def setUp(self): |
673 | 20 | client.open(url=u'http://launchpad.dev:8085/projects/+new') | 27 | self.client = WindmillTestClient('TestNewProjectStep1') |
674 | 21 | client.waits.forPageLoad(timeout=u'20000') | 28 | |
675 | 22 | 29 | def test_projects_plusnew_text_fields(self): | |
676 | 23 | client.type(text=u'dolphin', id='field.displayname') | 30 | """Test the text fields on step 1 of projects/+new page. |
677 | 24 | # The field is forced to lower case by a CSS text-transform, but that's | 31 | |
678 | 25 | # presentation and not testable. However, the field /is/ autofilled from | 32 | On step 1 of the wizard, the URL field gets autofilled from the Name |
679 | 26 | # the displayname field, and this we can test. | 33 | field. Also, the URL field will not accept invalid characters. |
680 | 27 | client.asserts.assertValue( | 34 | """ |
681 | 28 | id=u'field.name', | 35 | # Perform step 1 of the project registration, using information |
682 | 29 | validator=u'dolphin') | 36 | # that will yield search results. |
683 | 30 | # If we type into the Name field something that contains some trailing | 37 | self.client.open(url=u'http://launchpad.dev:8085/projects/+new') |
684 | 31 | # invalid characters, they don't end up in the URL field. | 38 | |
685 | 32 | client.type(text=u'dol@phin', id='field.displayname') | 39 | lpuser.SAMPLE_PERSON.ensure_login(self.client) |
686 | 33 | client.asserts.assertValue( | 40 | |
687 | 34 | id=u'field.name', | 41 | self.client.waits.forElement(id='field.displayname') |
688 | 35 | validator=u'dol') | 42 | self.client.type(text=u'dolphin', id='field.displayname') |
689 | 36 | # Typing directly into the URL field prevents the autofilling. | 43 | |
690 | 37 | client.type(text=u'mongoose', id='field.name') | 44 | # The field is forced to lower case by a CSS text-transform, but |
691 | 38 | client.type(text=u'dingo', id='field.displayname') | 45 | # that's presentation and not testable. However, the field /is/ |
692 | 39 | client.asserts.assertValue( | 46 | # autofilled from the displayname field, and this we can test. |
693 | 40 | id=u'field.name', | 47 | self.client.asserts.assertValue( |
694 | 41 | validator=u'mongoose') | 48 | id=u'field.name', |
695 | 42 | # But once we clear the URL field, autofilling is re-enabled. Type a | 49 | validator=u'dolphin') |
696 | 43 | # backspace character to trigger this. | 50 | # If we type into the Name field something that contains some trailing |
697 | 44 | client.type(text=u'\x08', id='field.name') | 51 | # invalid characters, they don't end up in the URL field. |
698 | 45 | client.type(text='hyena', id='field.displayname') | 52 | self.client.type(text=u'dol@phin', id='field.displayname') |
699 | 46 | client.asserts.assertValue( | 53 | self.client.asserts.assertValue( |
700 | 47 | id=u'field.name', | 54 | id=u'field.name', |
701 | 48 | validator=u'hyena') | 55 | validator=u'dol') |
702 | 56 | # Typing directly into the URL field prevents the autofilling. | ||
703 | 57 | self.client.type(text=u'mongoose', id='field.name') | ||
704 | 58 | self.client.type(text=u'dingo', id='field.displayname') | ||
705 | 59 | self.client.asserts.assertValue( | ||
706 | 60 | id=u'field.name', | ||
707 | 61 | validator=u'mongoose') | ||
708 | 62 | # But once we clear the URL field, autofilling is re-enabled. Type a | ||
709 | 63 | # backspace character to trigger this. | ||
710 | 64 | self.client.type(text=BACKSPACE, id='field.name') | ||
711 | 65 | self.client.type(text='hyena', id='field.displayname') | ||
712 | 66 | self.client.asserts.assertValue( | ||
713 | 67 | id=u'field.name', | ||
714 | 68 | validator=u'hyena') | ||
715 | 69 | |||
716 | 70 | |||
717 | 71 | def test_suite(): | ||
718 | 72 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
719 | 49 | 73 | ||
720 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step2.py' => 'lib/lp/registry/windmill/tests/test_plusnew_step2.py' | |||
721 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step2.py 2009-07-21 17:14:29 +0000 | |||
722 | +++ lib/lp/registry/windmill/tests/test_plusnew_step2.py 2009-12-11 20:25:26 +0000 | |||
723 | @@ -1,68 +1,97 @@ | |||
724 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
725 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
726 | 3 | 3 | ||
727 | 4 | """Test for form for creating a project.""" | ||
728 | 5 | |||
729 | 6 | __metaclass__ = type | ||
730 | 7 | __all__ = [] | ||
731 | 8 | |||
732 | 9 | import unittest | ||
733 | 10 | |||
734 | 4 | from windmill.authoring import WindmillTestClient | 11 | from windmill.authoring import WindmillTestClient |
735 | 5 | 12 | ||
736 | 6 | from canonical.launchpad.windmill.testing import lpuser | 13 | from canonical.launchpad.windmill.testing import lpuser |
737 | 7 | 14 | ||
799 | 8 | 15 | from lp.registry.windmill.testing import RegistryWindmillLayer | |
800 | 9 | def test_projects_plusnew_step_two(): | 16 | from lp.testing import TestCaseWithFactory |
801 | 10 | """Test the dynamic aspects of step 2 of projects/+new page. | 17 | |
802 | 11 | 18 | ||
803 | 12 | When the project being registered matches existing projects, the step two | 19 | class TestNewProjectStep2(TestCaseWithFactory): |
804 | 13 | page has some extra javascript-y goodness. At the start, there's a 'No' | 20 | """Test form for creating a new project.""" |
805 | 14 | button that hides the search results and reveals the rest of the project | 21 | |
806 | 15 | registration form. After that, there's a href that toggles between | 22 | layer = RegistryWindmillLayer |
807 | 16 | revealing the search results and hiding them. | 23 | |
808 | 17 | """ | 24 | def setUp(self): |
809 | 18 | client = WindmillTestClient('projects/+new step two dynamism') | 25 | self.client = WindmillTestClient('TestNewProjectStep2') |
810 | 19 | lpuser.SAMPLE_PERSON.ensure_login(client) | 26 | |
811 | 20 | 27 | def test_projects_plusnew_step_two(self): | |
812 | 21 | # Perform step 1 of the project registration, using information that will | 28 | """Test the dynamic aspects of step 2 of projects/+new page. |
813 | 22 | # yield search results. | 29 | |
814 | 23 | client.open(url=u'http://launchpad.dev:8085/projects/+new') | 30 | When the project being registered matches existing projects, the |
815 | 24 | client.waits.forPageLoad(timeout=u'20000') | 31 | step two page has some extra javascript-y goodness. At the |
816 | 25 | 32 | start, there's a 'No' button that hides the search results and | |
817 | 26 | client.type(text=u'Badgers', id='field.displayname') | 33 | reveals the rest of the project registration form. After that, |
818 | 27 | client.type(text=u'badgers', id='field.name') | 34 | there's a href that toggles between revealing the search results |
819 | 28 | client.type(text=u"There's the Badger", id='field.title') | 35 | and hiding them. |
820 | 29 | client.type(text=u'Badgers ate my firefox', id='field.summary') | 36 | """ |
821 | 30 | client.click(id=u'field.actions.continue') | 37 | |
822 | 31 | client.waits.forPageLoad(timeout=u'20000') | 38 | # Perform step 1 of the project registration, using information |
823 | 32 | # The h2 heading indicates that a search was performed. | 39 | # that will yield search results. |
824 | 33 | client.asserts.assertText( | 40 | self.client.open(url=u'http://launchpad.dev:8085/projects/+new') |
825 | 34 | id=u'step-title', | 41 | |
826 | 35 | validator=u'Check for duplicate projects') | 42 | lpuser.SAMPLE_PERSON.ensure_login(self.client) |
827 | 36 | # Clicking on the "No" button hides the button and search results, reveals | 43 | |
828 | 37 | # the form widgets, and reveals an href link for toggling the search | 44 | self.client.waits.forElement(id='field.displayname', timeout=u'20000') |
829 | 38 | # results. It also changes the h2 title to something more appropriate. | 45 | self.client.type(text=u'Badgers', id='field.displayname') |
830 | 39 | client.click(id=u'registration-details-buttons') | 46 | self.client.type(text=u'badgers', id='field.name') |
831 | 40 | client.asserts.assertText( | 47 | self.client.type(text=u"There's the Badger", id='field.title') |
832 | 41 | id=u'step-title', | 48 | self.client.type(text=u'Badgers ate my firefox', id='field.summary') |
833 | 42 | validator=u'Registration details') | 49 | self.client.click(id=u'field.actions.continue') |
834 | 43 | # The className for hidden elements is lazr-closed because it's set by | 50 | self.client.waits.forPageLoad(timeout=u'20000') |
835 | 44 | # the slide-in effect. For slide-out elements, it's lazr-opened. | 51 | # The h2 heading indicates that a search was performed. |
836 | 45 | client.asserts.assertProperty( | 52 | self.client.asserts.assertTextIn( |
837 | 46 | id='search-results', validator='className|lazr-closed') | 53 | id=u'step-title', |
838 | 47 | client.asserts.assertProperty( | 54 | validator=u'Check for duplicate projects') |
839 | 48 | id=u'launchpad-form-widgets', | 55 | |
840 | 49 | validator='className|lazr-opened') | 56 | # Clicking on the "No" button hides the button and search |
841 | 50 | client.asserts.assertNotProperty( | 57 | # results, reveals the form widgets, and reveals an href link |
842 | 51 | id=u'search-results-expander', | 58 | # for toggling the search results. It also changes the h2 title |
843 | 52 | validator='className|unseen') | 59 | # to something more appropriate. |
844 | 53 | # Clicking on the href expands the search results. | 60 | self.client.click(id=u'registration-details-buttons') |
845 | 54 | client.click(id='search-results-expander') | 61 | self.client.asserts.assertTextIn( |
846 | 55 | client.waits.forElement( | 62 | id=u'step-title', |
847 | 56 | xpath='//*[@id="search-results" and contains(@class, "lazr-opened")]', | 63 | validator=u'Registration details') |
848 | 57 | milliseconds=u'1000') | 64 | |
849 | 58 | client.asserts.assertProperty( | 65 | # The className for hidden elements is lazr-closed because it's |
850 | 59 | id=u'search-results', | 66 | # set by the slide-in effect. For slide-out elements, it's |
851 | 60 | validator='className|lazr-opened') | 67 | # lazr-opened. |
852 | 61 | # Clicking it again hides the results. | 68 | self.client.asserts.assertProperty( |
853 | 62 | client.click(id='search-results-expander') | 69 | id='search-results', validator='className|lazr-closed') |
854 | 63 | client.waits.forElement( | 70 | self.client.asserts.assertProperty( |
855 | 64 | xpath='//*[@id="search-results" and contains(@class, "lazr-closed")]', | 71 | id=u'launchpad-form-widgets', |
856 | 65 | milliseconds=u'1000') | 72 | validator='className|lazr-opened') |
857 | 66 | client.asserts.assertProperty( | 73 | self.client.asserts.assertNotProperty( |
858 | 67 | id=u'search-results', | 74 | id=u'search-results-expander', |
859 | 68 | validator='className|lazr-closed') | 75 | validator='className|unseen') |
860 | 76 | # Clicking on the href expands the search results. | ||
861 | 77 | self.client.click(id='search-results-expander') | ||
862 | 78 | self.client.waits.forElement( | ||
863 | 79 | xpath='//*[@id="search-results" ' | ||
864 | 80 | 'and contains(@class, "lazr-opened")]', | ||
865 | 81 | milliseconds=u'1000') | ||
866 | 82 | self.client.asserts.assertProperty( | ||
867 | 83 | id=u'search-results', | ||
868 | 84 | validator='className|lazr-opened') | ||
869 | 85 | # Clicking it again hides the results. | ||
870 | 86 | self.client.click(id='search-results-expander') | ||
871 | 87 | self.client.waits.forElement( | ||
872 | 88 | xpath='//*[@id="search-results" ' | ||
873 | 89 | 'and contains(@class, "lazr-closed")]', | ||
874 | 90 | milliseconds=u'1000') | ||
875 | 91 | self.client.asserts.assertProperty( | ||
876 | 92 | id=u'search-results', | ||
877 | 93 | validator='className|lazr-closed') | ||
878 | 94 | |||
879 | 95 | |||
880 | 96 | def test_suite(): | ||
881 | 97 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
882 | 69 | 98 | ||
883 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_product.py' => 'lib/lp/registry/windmill/tests/test_product.py' | |||
884 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_product.py 2009-07-17 00:26:05 +0000 | |||
885 | +++ lib/lp/registry/windmill/tests/test_product.py 2009-12-11 20:25:26 +0000 | |||
886 | @@ -1,24 +1,46 @@ | |||
887 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
888 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
889 | 3 | 3 | ||
911 | 4 | from canonical.launchpad.windmill.testing import lpuser | 4 | """Test product index page.""" |
912 | 5 | from canonical.launchpad.windmill.testing import widgets | 5 | |
913 | 6 | 6 | __metaclass__ = type | |
914 | 7 | test_title_inline_edit = widgets.InlineEditorWidgetTest( | 7 | __all__ = [] |
915 | 8 | url='http://launchpad.dev:8085/firefox', | 8 | |
916 | 9 | widget_id='product-title', | 9 | import unittest |
917 | 10 | expected_value='Mozilla Firefox', | 10 | |
918 | 11 | new_value='The awesome Mozilla Firefox', | 11 | from canonical.launchpad.windmill.testing import lpuser, widgets |
919 | 12 | name='test_title_inline_edit', | 12 | |
920 | 13 | suite=__name__, | 13 | from lp.registry.windmill.testing import RegistryWindmillLayer |
921 | 14 | user=lpuser.SAMPLE_PERSON) | 14 | from lp.testing import TestCaseWithFactory |
922 | 15 | 15 | ||
923 | 16 | test_programming_languages_edit = widgets.InlineEditorWidgetTest( | 16 | class TestProductIndexPage(TestCaseWithFactory): |
924 | 17 | url='http://launchpad.dev:8085/firefox', | 17 | """Test product index page.""" |
925 | 18 | widget_id='programminglang', | 18 | |
926 | 19 | widget_tag='span', | 19 | layer = RegistryWindmillLayer |
927 | 20 | expected_value='Not yet specified', | 20 | |
928 | 21 | new_value='C++', | 21 | def test_title_inline_edit(self): |
929 | 22 | name='test_proglang_inline_edit', | 22 | test = widgets.InlineEditorWidgetTest( |
930 | 23 | suite=__name__, | 23 | url='http://launchpad.dev:8085/firefox', |
931 | 24 | user=lpuser.SAMPLE_PERSON) | 24 | widget_id='product-title', |
932 | 25 | expected_value='Mozilla Firefox', | ||
933 | 26 | new_value='The awesome Mozilla Firefox', | ||
934 | 27 | name='test_title_inline_edit', | ||
935 | 28 | suite=__name__, | ||
936 | 29 | user=lpuser.SAMPLE_PERSON) | ||
937 | 30 | test() | ||
938 | 31 | |||
939 | 32 | def test_programming_languages_edit(self): | ||
940 | 33 | test = widgets.InlineEditorWidgetTest( | ||
941 | 34 | url='http://launchpad.dev:8085/firefox', | ||
942 | 35 | widget_id='programminglang', | ||
943 | 36 | widget_tag='span', | ||
944 | 37 | expected_value='Not yet specified', | ||
945 | 38 | new_value='C++', | ||
946 | 39 | name='test_proglang_inline_edit', | ||
947 | 40 | suite=__name__, | ||
948 | 41 | user=lpuser.SAMPLE_PERSON) | ||
949 | 42 | test() | ||
950 | 43 | |||
951 | 44 | |||
952 | 45 | def test_suite(): | ||
953 | 46 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
954 | 25 | 47 | ||
955 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_product_edit_people.py' => 'lib/lp/registry/windmill/tests/test_product_edit_people.py' | |||
956 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_product_edit_people.py 2009-07-17 00:26:05 +0000 | |||
957 | +++ lib/lp/registry/windmill/tests/test_product_edit_people.py 2009-12-11 20:25:26 +0000 | |||
958 | @@ -1,23 +1,44 @@ | |||
959 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
960 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
961 | 3 | 3 | ||
962 | 4 | """Test picker on +edit-people page.""" | ||
963 | 5 | |||
964 | 6 | __metaclass__ = type | ||
965 | 7 | __all__ = [] | ||
966 | 8 | |||
967 | 9 | import unittest | ||
968 | 10 | |||
969 | 4 | from canonical.launchpad.windmill.testing.widgets import ( | 11 | from canonical.launchpad.windmill.testing.widgets import ( |
970 | 5 | FormPickerWidgetTest) | 12 | FormPickerWidgetTest) |
971 | 6 | 13 | ||
989 | 7 | 14 | from lp.registry.windmill.testing import RegistryWindmillLayer | |
990 | 8 | test_product_edit_people_driver = FormPickerWidgetTest( | 15 | from lp.testing import TestCaseWithFactory |
991 | 9 | name='test_product_edit_people_driver', | 16 | |
992 | 10 | url='http://launchpad.dev:8085/firefox/+edit-people', | 17 | class TestProductEditPeople(TestCaseWithFactory): |
993 | 11 | short_field_name='driver', | 18 | """Test picker +edit-people page.""" |
994 | 12 | search_text='Perell\xc3\xb3', | 19 | |
995 | 13 | result_index=1, | 20 | layer = RegistryWindmillLayer |
996 | 14 | new_value='carlos') | 21 | |
997 | 15 | 22 | def test_product_edit_people_driver(self): | |
998 | 16 | test_product_edit_people_owner = FormPickerWidgetTest( | 23 | test = FormPickerWidgetTest( |
999 | 17 | name='test_product_edit_people_owner', | 24 | name='test_product_edit_people_driver', |
1000 | 18 | url='http://launchpad.dev:8085/firefox/+edit-people', | 25 | url='http://launchpad.dev:8085/firefox/+edit-people', |
1001 | 19 | short_field_name='owner', | 26 | short_field_name='driver', |
1002 | 20 | search_text='guadamen', | 27 | search_text='Perell\xc3\xb3', |
1003 | 21 | result_index=1, | 28 | result_index=1, |
1004 | 22 | new_value='guadamen') | 29 | new_value='carlos') |
1005 | 23 | 30 | test() | |
1006 | 31 | |||
1007 | 32 | def test_product_edit_people_owner(self): | ||
1008 | 33 | test = FormPickerWidgetTest( | ||
1009 | 34 | name='test_product_edit_people_owner', | ||
1010 | 35 | url='http://launchpad.dev:8085/firefox/+edit-people', | ||
1011 | 36 | short_field_name='owner', | ||
1012 | 37 | search_text='guadamen', | ||
1013 | 38 | result_index=1, | ||
1014 | 39 | new_value='guadamen') | ||
1015 | 40 | test() | ||
1016 | 41 | |||
1017 | 42 | |||
1018 | 43 | def test_suite(): | ||
1019 | 44 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
1020 | 24 | 45 | ||
1021 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_project_licenses.py' => 'lib/lp/registry/windmill/tests/test_project_licenses.py' | |||
1022 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_project_licenses.py 2009-07-17 02:25:09 +0000 | |||
1023 | +++ lib/lp/registry/windmill/tests/test_project_licenses.py 2009-12-11 20:25:26 +0000 | |||
1024 | @@ -1,131 +1,151 @@ | |||
1025 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
1026 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
1027 | 3 | 3 | ||
1028 | 4 | """Test project licenses picker.""" | ||
1029 | 5 | |||
1030 | 6 | __metaclass__ = type | ||
1031 | 7 | __all__ = [] | ||
1032 | 8 | |||
1033 | 9 | import unittest | ||
1034 | 10 | |||
1035 | 4 | from windmill.authoring import WindmillTestClient | 11 | from windmill.authoring import WindmillTestClient |
1036 | 5 | 12 | ||
1037 | 6 | from canonical.launchpad.windmill.testing import lpuser | 13 | from canonical.launchpad.windmill.testing import lpuser |
1038 | 7 | 14 | ||
1163 | 8 | 15 | from lp.registry.windmill.testing import RegistryWindmillLayer | |
1164 | 9 | def test_project_licenses(): | 16 | from lp.testing import TestCaseWithFactory |
1165 | 10 | """Test the dynamic aspects of the project license picker.""" | 17 | |
1166 | 11 | client = WindmillTestClient('firefox/+edit license picking') | 18 | |
1167 | 12 | lpuser.SAMPLE_PERSON.ensure_login(client) | 19 | class TestProjectLicenses(TestCaseWithFactory): |
1168 | 13 | 20 | """Test project licenses picker.""" | |
1169 | 14 | # The firefox project is as good as any. | 21 | |
1170 | 15 | client.open(url=u'http://launchpad.dev:8085/firefox/+edit') | 22 | layer = RegistryWindmillLayer |
1171 | 16 | client.waits.forPageLoad(timeout=u'20000') | 23 | |
1172 | 17 | 24 | def setUp(self): | |
1173 | 18 | # The Recommended table is visible. | 25 | self.client = WindmillTestClient('TestProjectLicenses') |
1174 | 19 | client.asserts.assertProperty( | 26 | |
1175 | 20 | id=u'recommended', | 27 | def test_project_licenses(self): |
1176 | 21 | validator='className|lazr-opened') | 28 | """Test the dynamic aspects of the project license picker.""" |
1177 | 22 | # But the More table is not. | 29 | # The firefox project is as good as any. |
1178 | 23 | client.asserts.assertProperty( | 30 | self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit') |
1179 | 24 | id=u'more', | 31 | self.client.waits.forPageLoad(timeout=u'20000') |
1180 | 25 | validator='className|lazr-closed') | 32 | |
1181 | 26 | # Neither is the Other choices. | 33 | lpuser.SAMPLE_PERSON.ensure_login(self.client) |
1182 | 27 | client.asserts.assertProperty( | 34 | |
1183 | 28 | id=u'special', | 35 | # The Recommended table is visible. |
1184 | 29 | validator='className|lazr-closed') | 36 | self.client.waits.forElementProperty( |
1185 | 30 | 37 | id=u'recommended', | |
1186 | 31 | # Clicking on the link exposes the More section though. | 38 | option='className|lazr-opened') |
1187 | 32 | client.click(id='more-expand') | 39 | # But the More table is not. |
1188 | 33 | client.waits.sleep(milliseconds=u'1000') | 40 | self.client.asserts.assertProperty( |
1189 | 34 | client.asserts.assertProperty( | 41 | id=u'more', |
1190 | 35 | id=u'more', | 42 | validator='className|lazr-closed') |
1191 | 36 | validator='className|lazr-opened') | 43 | # Neither is the Other choices. |
1192 | 37 | 44 | self.client.asserts.assertProperty( | |
1193 | 38 | # As does clicking on the Other choices section. | 45 | id=u'special', |
1194 | 39 | client.click(id='special-expand') | 46 | validator='className|lazr-closed') |
1195 | 40 | client.waits.sleep(milliseconds=u'1000') | 47 | |
1196 | 41 | client.asserts.assertProperty( | 48 | # Clicking on the link exposes the More section though. |
1197 | 42 | id=u'special', | 49 | self.client.click(id='more-expand') |
1198 | 43 | validator='className|lazr-opened') | 50 | self.client.waits.forElementProperty( |
1199 | 44 | 51 | id=u'more', | |
1200 | 45 | # Clicking on any opened link closes the section. | 52 | option='className|lazr-opened') |
1201 | 46 | client.click(id='recommended-expand') | 53 | |
1202 | 47 | client.asserts.assertProperty( | 54 | # As does clicking on the Other choices section. |
1203 | 48 | id=u'recommended', | 55 | self.client.click(id='special-expand') |
1204 | 49 | validator='className|lazr-closed') | 56 | self.client.waits.forElementProperty( |
1205 | 50 | 57 | id=u'special', | |
1206 | 51 | # The license details box starts out hidden. | 58 | option='className|lazr-opened') |
1207 | 52 | client.asserts.assertProperty( | 59 | |
1208 | 53 | id=u'license-details', | 60 | # Clicking on any opened link closes the section. |
1209 | 54 | validator='className|lazr-closed') | 61 | self.client.click(id='recommended-expand') |
1210 | 55 | 62 | self.client.waits.forElementProperty( | |
1211 | 56 | # But clicking on one of the Other/* licenses exposes it. | 63 | id=u'recommended', |
1212 | 57 | client.click(id='field.licenses.26') | 64 | option='className|lazr-closed') |
1213 | 58 | client.asserts.assertProperty( | 65 | |
1214 | 59 | id=u'license-details', | 66 | # The license details box starts out hidden. |
1215 | 60 | validator='className|lazr-opened') | 67 | self.client.asserts.assertProperty( |
1216 | 61 | 68 | id=u'license-details', | |
1217 | 62 | # Clicking on Other/Proprietary exposes the additional commercial | 69 | validator='className|lazr-closed') |
1218 | 63 | # licensing details. | 70 | |
1219 | 64 | client.asserts.assertProperty( | 71 | # But clicking on one of the Other/* licenses exposes it. |
1220 | 65 | id=u'proprietary', | 72 | self.client.click(id='field.licenses.26') |
1221 | 66 | validator='className|lazr-closed') | 73 | self.client.asserts.assertProperty( |
1222 | 67 | 74 | id=u'license-details', | |
1223 | 68 | client.click(id='field.licenses.25') | 75 | validator='className|lazr-opened') |
1224 | 69 | client.asserts.assertProperty( | 76 | |
1225 | 70 | id=u'license-details', | 77 | # Clicking on Other/Proprietary exposes the additional commercial |
1226 | 71 | validator='className|lazr-opened') | 78 | # licensing details. |
1227 | 72 | client.asserts.assertProperty( | 79 | self.client.asserts.assertProperty( |
1228 | 73 | id=u'proprietary', | 80 | id=u'proprietary', |
1229 | 74 | validator='className|lazr-opened') | 81 | validator='className|lazr-closed') |
1230 | 75 | 82 | ||
1231 | 76 | # Only when all Other/* items are unchecked does the details box get | 83 | self.client.click(id='field.licenses.25') |
1232 | 77 | # hidden. | 84 | self.client.asserts.assertProperty( |
1233 | 78 | client.click(id='field.licenses.26') | 85 | id=u'license-details', |
1234 | 79 | client.asserts.assertProperty( | 86 | validator='className|lazr-opened') |
1235 | 80 | id=u'license-details', | 87 | self.client.asserts.assertProperty( |
1236 | 81 | validator='className|lazr-opened') | 88 | id=u'proprietary', |
1237 | 82 | 89 | validator='className|lazr-opened') | |
1238 | 83 | client.click(id='field.licenses.25') | 90 | |
1239 | 84 | client.asserts.assertProperty( | 91 | # Only when all Other/* items are unchecked does the details box get |
1240 | 85 | id=u'license-details', | 92 | # hidden. |
1241 | 86 | validator='className|lazr-closed') | 93 | self.client.click(id='field.licenses.26') |
1242 | 87 | client.asserts.assertProperty( | 94 | self.client.asserts.assertProperty( |
1243 | 88 | id=u'proprietary', | 95 | id=u'license-details', |
1244 | 89 | validator='className|lazr-closed') | 96 | validator='className|lazr-opened') |
1245 | 90 | 97 | ||
1246 | 91 | # Clicking on "I haven't specified..." unchecks everything and closes the | 98 | self.client.click(id='field.licenses.25') |
1247 | 92 | # details box, but leaves the sections opened. | 99 | self.client.waits.forElementProperty( |
1248 | 93 | client.click(id='field.licenses.25') | 100 | id=u'license-details', |
1249 | 94 | client.asserts.assertProperty( | 101 | option='className|lazr-closed') |
1250 | 95 | id=u'license-details', | 102 | self.client.asserts.assertProperty( |
1251 | 96 | validator='className|lazr-opened') | 103 | id=u'proprietary', |
1252 | 97 | 104 | validator='className|lazr-closed') | |
1253 | 98 | client.asserts.assertChecked( | 105 | |
1254 | 99 | id=u'field.licenses.25') | 106 | # Clicking on "I haven't specified..." unchecks everything and |
1255 | 100 | 107 | # closes the details box, but leaves the sections opened. | |
1256 | 101 | client.click(id='license_pending') | 108 | |
1257 | 102 | client.asserts.assertNotChecked( | 109 | self.client.click(id='field.licenses.25') |
1258 | 103 | id=u'field.licenses.25') | 110 | self.client.waits.forElementProperty( |
1259 | 104 | 111 | id=u'license-details', | |
1260 | 105 | client.asserts.assertProperty( | 112 | option='className|lazr-opened') |
1261 | 106 | id=u'license-details', | 113 | |
1262 | 107 | validator='className|lazr-closed') | 114 | self.client.asserts.assertChecked( |
1263 | 108 | 115 | id=u'field.licenses.25') | |
1264 | 109 | # Submitting the form with items checked ensures that the next time the | 116 | |
1265 | 110 | # page is visited, those sections will be open. The Recommended section | 117 | self.client.click(id='license_pending') |
1266 | 111 | # is always open. | 118 | self.client.asserts.assertNotChecked( |
1267 | 112 | 119 | id=u'field.licenses.25') | |
1268 | 113 | client.click(id='field.licenses.25') | 120 | |
1269 | 114 | client.type(id='field.license_info', text='Foo bar') | 121 | self.client.asserts.assertProperty( |
1270 | 115 | client.click(id='field.licenses.3') | 122 | id=u'license-details', |
1271 | 116 | client.click(id='field.actions.change') | 123 | validator='className|lazr-closed') |
1272 | 117 | client.waits.forPageLoad(timeout=u'20000') | 124 | |
1273 | 118 | 125 | # Submitting the form with items checked ensures that the next | |
1274 | 119 | client.open(url=u'http://launchpad.dev:8085/firefox/+edit') | 126 | # time the page is visited, those sections will be open. The |
1275 | 120 | client.waits.forPageLoad(timeout=u'20000') | 127 | # Recommended section is always open. |
1276 | 121 | 128 | ||
1277 | 122 | client.asserts.assertProperty( | 129 | self.client.click(id='field.licenses.25') |
1278 | 123 | id=u'more', | 130 | self.client.type(id='field.license_info', text='Foo bar') |
1279 | 124 | validator='className|lazr-opened') | 131 | self.client.click(id='field.licenses.3') |
1280 | 125 | # Neither is the Other choices. | 132 | self.client.click(id='field.actions.change') |
1281 | 126 | client.asserts.assertProperty( | 133 | self.client.waits.forPageLoad(timeout=u'20000') |
1282 | 127 | id=u'special', | 134 | |
1283 | 128 | validator='className|lazr-opened') | 135 | self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit') |
1284 | 129 | client.asserts.assertProperty( | 136 | self.client.waits.forPageLoad(timeout=u'20000') |
1285 | 130 | id=u'license-details', | 137 | |
1286 | 131 | validator='className|lazr-opened') | 138 | self.client.asserts.assertProperty( |
1287 | 139 | id=u'more', | ||
1288 | 140 | validator='className|lazr-opened') | ||
1289 | 141 | # Neither is the Other choices. | ||
1290 | 142 | self.client.asserts.assertProperty( | ||
1291 | 143 | id=u'special', | ||
1292 | 144 | validator='className|lazr-opened') | ||
1293 | 145 | self.client.asserts.assertProperty( | ||
1294 | 146 | id=u'license-details', | ||
1295 | 147 | validator='className|lazr-opened') | ||
1296 | 148 | |||
1297 | 149 | |||
1298 | 150 | def test_suite(): | ||
1299 | 151 | return unittest.TestLoader().loadTestsFromName(__name__) | ||
1300 | 132 | 152 | ||
1301 | === modified file 'lib/lp/registry/windmill/tests/test_timeline_graph.py' | |||
1302 | --- lib/lp/registry/windmill/tests/test_timeline_graph.py 2009-10-29 13:40:37 +0000 | |||
1303 | +++ lib/lp/registry/windmill/tests/test_timeline_graph.py 2009-12-11 20:25:26 +0000 | |||
1304 | @@ -1,6 +1,11 @@ | |||
1305 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
1306 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
1307 | 3 | 3 | ||
1308 | 4 | """Test for timeline graph widget.""" | ||
1309 | 5 | |||
1310 | 6 | __metaclass__ = type | ||
1311 | 7 | __all__ = [] | ||
1312 | 8 | |||
1313 | 4 | import unittest | 9 | import unittest |
1314 | 5 | 10 | ||
1315 | 6 | from windmill.authoring import WindmillTestClient | 11 | from windmill.authoring import WindmillTestClient |
1316 | @@ -9,6 +14,7 @@ | |||
1317 | 9 | from lp.testing import TestCaseWithFactory | 14 | from lp.testing import TestCaseWithFactory |
1318 | 10 | 15 | ||
1319 | 11 | class TestTimelineGraph(TestCaseWithFactory): | 16 | class TestTimelineGraph(TestCaseWithFactory): |
1320 | 17 | """Test timeline graph widget.""" | ||
1321 | 12 | 18 | ||
1322 | 13 | layer = RegistryWindmillLayer | 19 | layer = RegistryWindmillLayer |
1323 | 14 | 20 | ||
1324 | 15 | 21 | ||
1325 | === modified file 'lib/lp/translations/tests/test_translationimportqueue.py' | |||
1326 | --- lib/lp/translations/tests/test_translationimportqueue.py 2009-11-19 11:24:43 +0000 | |||
1327 | +++ lib/lp/translations/tests/test_translationimportqueue.py 2009-12-11 20:25:26 +0000 | |||
1328 | @@ -5,6 +5,7 @@ | |||
1329 | 5 | 5 | ||
1330 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
1331 | 7 | 7 | ||
1332 | 8 | import transaction | ||
1333 | 8 | import unittest | 9 | import unittest |
1334 | 9 | 10 | ||
1335 | 10 | from zope.component import getUtility | 11 | from zope.component import getUtility |
1336 | @@ -17,25 +18,27 @@ | |||
1337 | 17 | from canonical.testing import LaunchpadZopelessLayer | 18 | from canonical.testing import LaunchpadZopelessLayer |
1338 | 18 | 19 | ||
1339 | 19 | 20 | ||
1342 | 20 | class TestTranslationImportQueueEntryStatus(TestCaseWithFactory): | 21 | class TestCanSetStatusBase(TestCaseWithFactory): |
1343 | 21 | """Test handling of the status of a queue entry.""" | 22 | """Base for tests that check that canSetStatus works .""" |
1344 | 22 | 23 | ||
1345 | 23 | layer = LaunchpadZopelessLayer | 24 | layer = LaunchpadZopelessLayer |
1346 | 25 | dbuser = None | ||
1347 | 26 | entry = None | ||
1348 | 24 | 27 | ||
1349 | 25 | def setUp(self): | 28 | def setUp(self): |
1350 | 26 | """Set up context to test in.""" | 29 | """Set up context to test in.""" |
1352 | 27 | super(TestTranslationImportQueueEntryStatus, self).setUp() | 30 | super(TestCanSetStatusBase, self).setUp() |
1353 | 28 | 31 | ||
1354 | 29 | self.queue = getUtility(ITranslationImportQueue) | 32 | self.queue = getUtility(ITranslationImportQueue) |
1355 | 30 | self.rosetta_experts = ( | 33 | self.rosetta_experts = ( |
1356 | 31 | getUtility(ILaunchpadCelebrities).rosetta_experts) | 34 | getUtility(ILaunchpadCelebrities).rosetta_experts) |
1357 | 32 | self.productseries = self.factory.makeProductSeries() | 35 | self.productseries = self.factory.makeProductSeries() |
1358 | 33 | self.uploaderperson = self.factory.makePerson() | 36 | self.uploaderperson = self.factory.makePerson() |
1364 | 34 | self.potemplate = self.factory.makePOTemplate( | 37 | |
1365 | 35 | productseries=self.productseries) | 38 | def _switch_dbuser(self): |
1366 | 36 | self.entry = self.queue.addOrUpdateEntry( | 39 | if self.dbuser != None: |
1367 | 37 | 'demo.pot', '#demo', False, self.uploaderperson, | 40 | transaction.commit() |
1368 | 38 | productseries=self.productseries, potemplate=self.potemplate) | 41 | self.layer.switchDbUser(self.dbuser) |
1369 | 39 | 42 | ||
1370 | 40 | def _assertCanSetStatus(self, user, entry, expected_list): | 43 | def _assertCanSetStatus(self, user, entry, expected_list): |
1371 | 41 | # Helper to check for all statuses. | 44 | # Helper to check for all statuses. |
1372 | @@ -49,6 +52,7 @@ | |||
1373 | 49 | RosettaImportStatus.IMPORTED, | 52 | RosettaImportStatus.IMPORTED, |
1374 | 50 | RosettaImportStatus.NEEDS_REVIEW, | 53 | RosettaImportStatus.NEEDS_REVIEW, |
1375 | 51 | ] | 54 | ] |
1376 | 55 | self._switch_dbuser() | ||
1377 | 52 | # Do *not* use assertContentEqual here, as the order matters. | 56 | # Do *not* use assertContentEqual here, as the order matters. |
1378 | 53 | self.assertEqual(expected_list, | 57 | self.assertEqual(expected_list, |
1379 | 54 | [entry.canSetStatus(status, user) | 58 | [entry.canSetStatus(status, user) |
1380 | @@ -71,6 +75,7 @@ | |||
1381 | 71 | # If the entry has no import target set, even Rosetta experts | 75 | # If the entry has no import target set, even Rosetta experts |
1382 | 72 | # cannot set it to approved. | 76 | # cannot set it to approved. |
1383 | 73 | self.entry.potemplate = None | 77 | self.entry.potemplate = None |
1384 | 78 | self.entry.pofile = None | ||
1385 | 74 | self._assertCanSetStatus(self.rosetta_experts, self.entry, | 79 | self._assertCanSetStatus(self.rosetta_experts, self.entry, |
1386 | 75 | # A B D F I NR | 80 | # A B D F I NR |
1387 | 76 | [False, True, True, True, True, True]) | 81 | [False, True, True, True, True, True]) |
1388 | @@ -115,5 +120,66 @@ | |||
1389 | 115 | [False, False, False, False, False, False]) | 120 | [False, False, False, False, False, False]) |
1390 | 116 | 121 | ||
1391 | 117 | 122 | ||
1392 | 123 | class TestCanSetStatusPOTemplate(TestCanSetStatusBase): | ||
1393 | 124 | """Test canStatus applied to an entry with a POTemplate.""" | ||
1394 | 125 | |||
1395 | 126 | def setUp(self): | ||
1396 | 127 | """Create the entry to test on.""" | ||
1397 | 128 | super(TestCanSetStatusPOTemplate, self).setUp() | ||
1398 | 129 | |||
1399 | 130 | self.potemplate = self.factory.makePOTemplate( | ||
1400 | 131 | productseries=self.productseries) | ||
1401 | 132 | self.entry = self.queue.addOrUpdateEntry( | ||
1402 | 133 | 'demo.pot', '#demo', False, self.uploaderperson, | ||
1403 | 134 | productseries=self.productseries, potemplate=self.potemplate) | ||
1404 | 135 | |||
1405 | 136 | |||
1406 | 137 | class TestCanSetStatusPOFile(TestCanSetStatusBase): | ||
1407 | 138 | """Test canStatus applied to an entry with a POFile.""" | ||
1408 | 139 | |||
1409 | 140 | def setUp(self): | ||
1410 | 141 | """Create the entry to test on.""" | ||
1411 | 142 | super(TestCanSetStatusPOFile, self).setUp() | ||
1412 | 143 | |||
1413 | 144 | self.potemplate = self.factory.makePOTemplate( | ||
1414 | 145 | productseries=self.productseries) | ||
1415 | 146 | self.pofile = self.factory.makePOFile('eo', potemplate=self.potemplate) | ||
1416 | 147 | self.entry = self.queue.addOrUpdateEntry( | ||
1417 | 148 | 'demo.po', '#demo', False, self.uploaderperson, | ||
1418 | 149 | productseries=self.productseries, pofile=self.pofile) | ||
1419 | 150 | |||
1420 | 151 | |||
1421 | 152 | class TestCanSetStatusPOTemplateWithQueuedUser(TestCanSetStatusPOTemplate): | ||
1422 | 153 | """Test handling of the status of a queue entry with 'queued' db user. | ||
1423 | 154 | |||
1424 | 155 | The archive uploader needs to set (and therefore check) the status of a | ||
1425 | 156 | queue entry. It connects as a different database user and therefore we | ||
1426 | 157 | need to make sure that setStatus stays within this user's permissions. | ||
1427 | 158 | This is the version for POTemplate entries. | ||
1428 | 159 | """ | ||
1429 | 160 | |||
1430 | 161 | dbuser = 'queued' | ||
1431 | 162 | |||
1432 | 163 | |||
1433 | 164 | class TestCanSetStatusPOFileWithQueuedUser(TestCanSetStatusPOFile): | ||
1434 | 165 | """Test handling of the status of a queue entry with 'queued' db user. | ||
1435 | 166 | |||
1436 | 167 | The archive uploader needs to set (and therefore check) the status of a | ||
1437 | 168 | queue entry. It connects as a different database user and therefore we | ||
1438 | 169 | need to make sure that setStatus stays within this user's permissions. | ||
1439 | 170 | This is the version for POFile entries. | ||
1440 | 171 | """ | ||
1441 | 172 | |||
1442 | 173 | dbuser = 'queued' | ||
1443 | 174 | |||
1444 | 175 | |||
1445 | 118 | def test_suite(): | 176 | def test_suite(): |
1447 | 119 | return unittest.TestLoader().loadTestsFromName(__name__) | 177 | """Add only specific test cases and leave out the base case.""" |
1448 | 178 | suite = unittest.TestSuite() | ||
1449 | 179 | suite.addTest(unittest.makeSuite(TestCanSetStatusPOTemplate)) | ||
1450 | 180 | suite.addTest(unittest.makeSuite(TestCanSetStatusPOFile)) | ||
1451 | 181 | suite.addTest( | ||
1452 | 182 | unittest.makeSuite(TestCanSetStatusPOTemplateWithQueuedUser)) | ||
1453 | 183 | suite.addTest(unittest.makeSuite(TestCanSetStatusPOFileWithQueuedUser)) | ||
1454 | 184 | return suite | ||
1455 | 185 |
Summary
-------
Moved the remaining registry windmill tests from launchpad/ windmill/ tests to lib/lp/ registry/ windmill/ tests.
lib/canonical/
Implementation details ------- ------- -
-------
Most of the changes just involve boilerplate to convert the tests
to unittests, indenting functions that became methods, and replacing
client with self.client.
I've included a smaller diff below of the changes that were made to fix
regressions since these tests had not been automatically run. I also
encountered authentication problems with the lpuser module's
ensure_login() method. Some of the tests use helper functions from a
different module that creates a new windmill client each time the
function is called. I assume there is something in the initialization of
the new client that invalidates the cookie from the last client,
therefore, I have to load a page in the new client before calling
ensure_login() so that it can find the "Login" link, otherwise it
assumes it is still logged in just fine.
lib/lp/ registry/ browser/ product. py
The windmill test was using foo.bar instead of the owner of the
project, so it seemed better to fix this by allowing anyone with
launchpad.Edit access to be able to see the programming language
fields inline editing icon.
lib/lp/ registry/ templates/ milestone- index.pt registry/ windmill/ tests/test_ add_milestone. py
lib/lp/
Creating a release now takes you to the milestone/release index
page instead of the series index page. The ids were added to
simplify the tests.
lib/lp/ registry/ templates/ product- new.pt
node.attach() was replaced with node.on(), so this functionality
was actually broken in production.
lib/lp/ registry/ windmill/ tests/test_ plusnew_ step1.py registry/ windmill/ tests/test_ plusnew_ step2.py registry/ windmill/ tests/test_ product. py registry/ windmill/ tests/test_ project_ licenses. py
lib/lp/
lib/lp/
lib/lp/
Tests
-----
./bin/test -vv --layer= RegistryWindmil lLayer
{{{
=== modified file 'lib/canonical/ launchpad/ windmill/ testing/ widgets. py' launchpad/ windmill/ testing/ widgets. py 2009-10-29 14:23:16 +0000 launchpad/ windmill/ testing/ widgets. py 2009-12-11 00:22:50 +0000 ent(self. suite) open(url= self.url)
--- lib/canonical/
+++ lib/canonical/
@@ -60,10 +60,10 @@
* reloads and verifies that the new value sticked.
"""
client = WindmillTestCli
+ client.
- client. open(url= self.url)
client. waits.forPageLo ad(timeout= constants. PAGE_LOAD)
widget_ base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id)
client. waits.forElemen t(
@@ -298,13 +298,15 @@
def __call__(self): ent(self. suite) ensure_ login(client)
client = WindmillTestCli
- self.user.
# Load page.
client. open(url= self.url) waits.forPageLo ad(timeout= constants. PAGE_LOAD) ensure_ login(client)
- client.
+
+ self.user.
# Click on "Choose" link to show picker for the given field. waits.forElemen t( choose_ link_id, timeout= constants. PAGE_LOAD)
client. click(id= self.choose_ link_id)
+ client.
+ id=self.
# Search picker.
=== modified file 'lib/lp/regis...